kinetic-core 0.2.0

Core daemon primitives, VDF management, and network utilities for the Kinetic Network.
Documentation
//! Protocol-level constants and magic numbers for the Kinetic network.
//!
//! These values define the immutable characteristics of the network (like the TLD
//! or the DID prefix) and are compiled directly into the binary. To fork the network
//! and create an incompatible variant, developers should change these values here
//! before recompiling.

// ============================================================================
// 1. DYNAMIC NETWORK CONFIGURATION
// Generated automatically from network.json by build.rs.
// Includes: TLD, NETWORK_ID, GOVERNANCE_MODEL, BOOTSTRAP_NODES, etc.
// ============================================================================
include!(concat!(env!("OUT_DIR"), "/network_constants.rs"));

// ============================================================================
// 2. GOVERNANCE CONSENSUS TIMINGS & LIMITS
// Used by: `kinetic-core/src/governance/logic.rs` and engines
// (Now dynamically injected from network.json via build.rs)
// ============================================================================

// ============================================================================
// 3. GOVERNANCE CRYPTOGRAPHY
// Used by: `kinetic-core/src/governance/logic.rs` and engines
// ============================================================================

/// The target number of leading zero bits required for PoW mining.
pub const POW_DIFFICULTY_BITS: u32 = 15;

/// PBKDF2 iterations for wallet derived keys
pub const WALLET_PBKDF2_ITERATIONS: u32 = 600000;

/// PBKDF2 iterations for key generation
pub const KEYGEN_PBKDF2_ITERATIONS: u32 = 2048;

/// Argon2 memory cost in KB
pub const ARGON2_MEMORY_COST_KB: u32 = 16384;

// --- PRODUCTION KEYS ---
/// Production keys
pub mod prod_keys {
    /// The offline, air-gapped ML-DSA-65 post-quantum root of trust key (hex-encoded).
    pub const ROOT_PUBLIC_KEY_HEX: &str = "75013e2180ea112511e0dd3ca607da0a941934856b6dacf8e3fd5f897a0934cf220ffcc4ff54d79b126e8c957b46a9a9336dd227f3644375eba1ac6c0ef4207250974301baa27340a253698cfa6a80ae9622cf7f7d07c0c5d178133b414012536ad13bc074fda7dcc22bc76c1602eed80359bba28b588b29f9a9aa5d855a7157171fc7e13605a7753d507dad9f34f3c251edb08ebbc70b95138b7d22c4d2cce48b9389ec7811a2160211809dd9fa616b020910bc60c231f98c81fa4bff22763481442c178a41276d5d88efc42d8cb8b6cb8b6fc188ffd4bd6347cf270c196bf6f7925ae8d7c1c97133d9e10434eac5351b9c14279e652459f6497ca6db2a8cd31cf6a19ee4b4c95d73460918108fa1268df102d62827d1dffe34063ad422e68309ba50fe0297f06426c36a8e2fbb7cb11711059e9913b61a887586ef913c8e4c9ebb6b3f832f7162ac00d4cf22cbd4f778e1e804c859a0402f443f046136bf937923a8a0902e4942efa85cb9da3640d968ea8a4a892b05a108c3b518d7bf0de23eb24378de7e3bf2e45ada4a773093bf3fcc915bb2745d4eaf8b67ea9e5a91967509d0a47400e88ea49af1bda2211677c19fc710d23610f6fd24c030354451a367eda71b7adc94f4fc82cc4bf2e93bf94fa32961a4c5a2484a9eb8e34830e790867517920f620578188c11a60f1e9bd1f547e316c3fb11395cdfe8839f9ebe87ab8cdb9ab85d63a504a99fb9cf08840e1c8e3d03ad00fbf655cce431193521a64a0ed48264203dfe84154746265b2d388ecb61e90318bcd4e40dbd2172b4c242c7263b5081a4821988e94aed44e087ebc306328d270794c45a32e7c8d508753a43f9800899834e88e8caf5c6844a0a970c5451f5b5a34477bc9b608cc59168230c8f627a2a8145debb5f066e3dabf96361070b53fe6636f9dbb08a243a96f1b89acbe6980f2a911f391a81f356c294489ae4de273e655012ec70b6d53be931deddbacdeaff207c43818f6b8821a0651bfaa6f421559f3e2bacede854950c8edc2bcfb7ad2ed39bd35aa517025cc8da5483ea7dd24da49d0079c8b81a14f667463553c18fb178f88ff7f710e54c97b596a1bbcf18680d36a9d62de77c248fd080cff89c234ed36de0404dc1776acb3631723c244daded46b133cb2908ca6e6ed16a0fc02557a3e64f1a7f2d5d651f19494ba9b03c624defbc00315a2a3e263dcd63e523124056086df1862200208e1115eb88ed10f1757bcf5a1812eb933192fe3a829ac02111162ea3a56a666f4a59c2e19dd0a3f1ae7597706712890a26f429b8e0ecae2fc47cbf88d05482d0b1e970c33834ef05c363dfb067bdbf5cf0c8e0c70c86e306d2be5e1a5de386bce0f7c4660891c5a04bc3c95ef2ab8a5230c9700ca659e3a0f7ae23afd69a1551d0425fd076985eed9b341e2ecac5be72f9fdb0249a3d50845618c520c0efa427cec20e4608c06ff769fe8102abb6bf7985a968c127a98d66d8b376613f55bb548c3efb8f21cef6fb15220754f41427d0686d7eb6e8bae70b1681c071260f2dc35fdf790244581505558f3529a0c62d9b485f0875c07c4b9a0f52e78719a1c758600e34299e1d7c4e8dcf6a2650f2d7c0ea5ad123319311bbcca269be42d031bcc58c4957b4bc81d366d9e2e26150d409e0d0fc3192309ed4a0242dd0e5befaa2e71097b8a45a830f92f3bc906ac7f6747b50af207e12f64a73c64ff3b3a47158043dd2d9d91b69df24e676c0f22ca5352247071fa2d0543e4a0b79003487930ad2a8143d32b345e59df55ec27c3c69d5a41696805d3648fe971010d6c8e99f80a3f37cfec810232e4f00e34557022b4916c79dc4cc25ec2e1bd3001972d31c1dbf6872c3c5a05a255d8b4add3df679c26906ae051210c958f304a08d41d60fcaef04de3acc409305a2cb7ae1350dbc684aa0d5c7940b27680a4ce5fefd5d2ed15953d658e8ca4f7aa8a3ae0ac589988364196a02952006ac73d831e9a0b932d0fa359f09c45715f802e1078aea10a15a964c58dd0b8429ef90fd04d8a42736aa993ba7aa06bf04e9d68f20b7370307dcdbca8c2366abb2d7887750e5402388683f921d8ba3486b595aa39b7dd0e57df995838d69eb71cf0d3b73826ca0b3df60a41dda4b8fc20793f57f8f67f50fdbf9b38f902ba83f750dd1c2bb121817680f844ecab047d4fcd6ebbc74bdd83e95881e4d3fbd29b6f6ab6e7e7517072f898d24254722e780ea081936506389a7588f5ac071918ebe0a7b56b3dd15796c1d4061820367204da0179dc5143c30744415a808339b97ecd186fdc79c89fbff7ce840e2d721a729680a144dfb0ca5d15d1e1e65b37d26bb8ed6eb671ba1fbcc48b35e6a811ea5d1df2dcdb02c79960c2da21bd30de91ee9fb7e91804019be4b653a9cd0edf005409659310158aaf1c0c1847cfbaeb7add046ab2e144b50b1fc2454483cc47081b844a41c145b05c619baf21cfcb9d655ef5516a443ccbecd2746818d7249852147a06b401e7b2b572f8702c86d7daca22f28ab28ed26b2b6c0903fc3895be817292576a54b8001e33c5b427eb08b3e2b3c23f97eddce86fd855401d01af2c3fcead9dd44dc1f62c5a2a19f91c9a23bd6995f1d9271c44168eb263bddaafed1bcffad0f136c7c359438439288a218d4c90129e5e9be7f6fe9d78007c77628406f776b0964fddf0ba3a84b9cdbfd10b84f6e0e9fa7e423bc7946cc26ea6aaaebfa9fd4c67933b94c57f12830d59b99";
}

#[cfg(not(test))]
pub use prod_keys::*;

// --- TEST KEYS ---
/// Test keys
pub mod test_keys {
    /// The offline, air-gapped ML-DSA-65 post-quantum root of trust key (hex-encoded, test key).
    pub const ROOT_PUBLIC_KEY_HEX: &str = "efbba31da7eec01beb466110b554b4422cb3a9097d6dddaf827a63693f8796087c2c9bfb61a49c0a648c0d2cb645e91fb5c27891a0a1d5d09940c6c28c689facc2f9ef13e8d0bc88de8e6c55676d79f9dd8f419c08d469bd1d88c65ff0131d254ebce4e849eb412696363dce9976fa04c0321deedc8497fb68dd4f2abdc18e404f326d77daf0aa270b2d3e1999759970da52fc7aefff386ec7a990bfa6a7f71373b7767ce41c84c5219aa68579cfbf9dea506a8d16cbebacc8b3af872b206a69eeada29585ba8badf269914199635a05394492c9fa449a05fe45573eaee89a2d0d0632855f3efe4a94caffd467abf95760913f731c16bfdfedb25f73b2ac2558d2bf2a43d7f07748cbb0abd7386bcdd8b1810e03ee5ee372a1417fdbb4da9ff88d50bbf9864a080a1068e81b1c0b0fa93318143d2bbff7e0fa116edd94fc0ca565a13294d8b98dc702d17bbe6eb1cd989dde9297e4c75c2c38b6a5ed2385d87b98423d33e9fcf80902598643623e0f10f3e8db5fedead9b2a5cd71981c304017cc503daa0c9cceb3b0b3c17db8985ef6e73fe318b2aae1a2aa855539b4118987eb822905d22b1086e8de65e9d636162b4a25c2f25313bf5cc9b7b17f6df9da5452dfc76c7fac48f017c130822ecac4224f68d9cd4aeaba9eaa0d86667f32127a861dbb648a03ddcb168a19f8ab367dbe31eebea4952e3fdf04db86403ba39edb34d75eadd5fdcfe1527cc28dd2758031041d898d407acd40c07aae6db1095ae693ee37bbf99f47d2d4113f8d92f7072f882e8e588ee8a292ee832c9719e863edb1e8c9c77cca2c6163729a30edbed2b51fc68fdcc30a541fc7c8cddcb799f87eba7ad161879ff1e98a7837a7bbf108e49784db0cac6664d0a40cd195f70b012c652b3b81d28786f8537ca6eece113bbd7356a45f825e135ef47e3118c5df2b8b766b36342e1680ea00a07da27ac754a9225d633bda2b1c92a8a316ce629b276306a53fa4ac294be1b150f8e7cfc6048d0a1e3b1198aee97216fa20b59982aba74cf1df4654c374efb0127ced46ce5fd7f6243a5a20e9d3528f46cf58499b7932d08e386aa111def3a4f66150de2b959c899b06d7b55e9d88e54bab5fc003ee950f336fd386d94f5edb037674e1371acd860cf4f8aa9924bde0d11b15756a31649012889982ddae448a1ece884601f999f5bafeb730ba2dd739135b01bbc42f58de46e57e21c8c4bb1d8d4b0cee58b3692de887b097b120dc7ac4ca9f23faa3d7123f8af983706d43b6166a48892019aa48e0498549041607daeb3f2c4435cc3c4806929ea8a57ef62e17f27c75e4c3b284d5c2139b3d96c8a4ef1a1ab0b2a96d7a5b294bf095624104978b3bd71e7f4255f41c82cae6f7ca791de40fa490e00ea7277addad221e2ef049c152f7acda3778e96e3f53665479a7cf77b78bc73b7e4ec683f64afd7db495a2ba7ff627ac259b4993d8fe8b8b1528dd75515c350d2cffef84442e53cb6c34d22711ed60ba7c7e105ab90de50acd8c139b5e46d340c8db47a794ea684ada788c1f3774f6c9b06500c1da5279be5cd753405c9dab21b3fb5fcc817e18c0526ebe4771d4acf806eff066a144f8f1a82350326db2e1d90507c27ee44e147ef57468639e21c9ec8f5d088e3db11fabb668a9b01fc025bff53bb87910a34284d90083adbc2a74bcb2ae37d6bad6b00c5c9d5cad2bdfee4502250757032e5d6bfd10c8dfd53390807cce20f8c9c7b2c23802a592d5257b45f8b80770ec1b594cbae781f31869d54cdad45e8e4ba2847677f8268b7ab2782980286968d7c8928b65d7a76041acace704f280778f97a7746d967d0a05e4b78950af666b991a50ecf466a9b645083ba44105018a3e71459568786e44063ce0dce793cc18ef81a71b56050dfd87819e5cd13a74c6efdeab6924a2513fb7cc5a76bf2f356c8766c73a303d8b26be73ec9da22d061b59227b93261c5fef5bfe6cf1dc6db316e87852f64832fe7652c406c0ca81bf54d880ac871a46c8a23fb318a4ecdf671523a1afb7b9f0cb8ecec77025219e7cf29e93c70e907be3beb1d6a05fe532b2df67b391eee846195fe009f163d6848eb51cf19b7860e1fedf4cd30d2e9e6e558277f45eb2cefed6ef80ad80a6682298a593aea75f58636ef8d4c0f5ceed800c842d57625fbf2fb2f94966cb07f53f21143955bcc8e7882cc51e2b6d0d0e9447e4f00658b58aef5e8b6a74be9a7a54ec888d9851e1da2e57def369799be2d63acd04ad19385778078975329b167194a8f21831de8c2bc94723625ae1941b49919460ba66b3517aa7eddbccca4ead914a7f7264d09c86ed97b64797d35f732afb1e0b2f2b4e1454dadf0da4636a3c78cd1ab271d58f1a9c9eaeaffb1e2b8d61ba77ec04a521da678e9b789814dde02907de5c7d560b4e9c55c627f6063da643809100f32c0ebe3ffb579cffae842f1a5a58e31ca480c6087b8936086ae214f49be6da894d960466278bb10227af60795f16d9e1db3c38c0bdcadf6e81cf4c7178df6dc5c986582d628238bac9c12f899e3c8f07abf6975a71c2bd95f1de119ad09cd669f0345b1a897ad2aa08518ea8e81fca570019d08edb2c7aefa03871136304e7eb38f1ea2e8e0a72e58d075becc80f689463bbc9084ce040b83a14667efa0cb1e121d405b7ec3eaa9df929e4c3cfa765b518a25edc470a5f12e696f65e1abf18068281c2ef881e76c4b11d36bb7deb910c99d28ece5b70fdb245dc47";
}

#[cfg(test)]
pub use test_keys::*;
// ============================================================================
// ============================================================================
// 4. STORAGE & NETWORK PREFIXES & KADEMLIA CONSTANTS
// ============================================================================

/// The Time-To-Live (TTL) for Kademlia DHT provider records in seconds (4 hours).
pub const KADEMLIA_PROVIDER_RECORD_TTL_SECS: u64 = 4 * 3600;

/// The interval at which Kademlia provider records are republished in seconds (3 hours).
pub const KADEMLIA_PUBLICATION_INTERVAL_SECS: u64 = 3 * 3600;

/// Purpose string used in PBKDF2 for deriving ML-DSA-65 deterministic governance keys.
pub const KINETIC_GOVERNANCE_KEY_PURPOSE: &str =
    concat!(env!("KINETIC_NETWORK_ID_UPPER"), "_GOVERNANCE_KEY_v1_PQC");

/// Prefix for storing registered `.kin` names in local Sled/DB storage.
/// Dynamically namespaced with `NETWORK_ID` to prevent cross-network key collisions.
pub const DB_PREFIX_OWNED_NAMES: &[u8] =
    concat!("n:", env!("KINETIC_NETWORK_ID"), "_owned_names").as_bytes();

/// Key prefix for storing VDF reveal proof payloads in local Sled/DB storage.
pub const DB_PREFIX_REVEAL: &str = concat!("n:", env!("KINETIC_NETWORK_ID"), "_reveal:");

/// Key prefix for storing banned peer multiaddrs in local Sled/DB storage.
pub const DB_PREFIX_BANNED_PEER: &str = concat!("n:", env!("KINETIC_NETWORK_ID"), "_banned_peer:");

/// Storage key for persisting the latest processed Drand kyn number.
pub const DB_PREFIX_LAST_DRAND: &[u8] =
    concat!("n:", env!("KINETIC_NETWORK_ID"), "_last_drand_kyn").as_bytes();

/// Database namespace for the P2P ping proxy subsystem.
pub const DB_NAME_PING: &str = concat!("n:", env!("KINETIC_NETWORK_ID"), "_ping_db");

/// libp2p Gossipsub topic for network governance messages and council signatures.
/// Dynamically namespaced with `NETWORK_ID` to isolate governance propagation across networks.
pub const GOSSIP_TOPIC_GOVERNANCE: &str = concat!(env!("KINETIC_NETWORK_ID"), "_governance");

/// libp2p Gossipsub topic for broadcasting Drand randomness beacon kyns.
/// Dynamically namespaced with `NETWORK_ID` to separate network kyn channels.
pub const GOSSIP_TOPIC_DRAND: &str = concat!("drand_kyn_", env!("KINETIC_NETWORK_ID"));

// ============================================================================
// 5. ENVIRONMENT VARIABLES
// ============================================================================

/// Environment variable string to override the data directory path (e.g. `KINETIC_MAINNET_DATA_DIR`).
pub const ENV_DATA_DIR: &str = concat!(env!("KINETIC_NETWORK_ID_UPPER"), "_DATA_DIR");
/// Environment variable string to override the `config.toml` path (e.g. `KINETIC_MAINNET_CONFIG_PATH`).
pub const ENV_CONFIG_PATH: &str = concat!(env!("KINETIC_NETWORK_ID_UPPER"), "_CONFIG_PATH");
/// Environment variable string to override the identity key file path (e.g. `KINETIC_MAINNET_KEY_PATH`).
pub const ENV_KEY_PATH: &str = concat!(env!("KINETIC_NETWORK_ID_UPPER"), "_KEY_PATH");
/// Environment variable string to override the P2P host listen port (e.g. `KINETIC_MAINNET_HOST_P2P_PORT`).
pub const ENV_HOST_P2P_PORT: &str =
    concat!(env!("KINETIC_NETWORK_ID_UPPER"), "_HOST_P2P_PORT");
/// Environment variable string to override the backend proxy port for the host (e.g. `KINETIC_MAINNET_HOST_BACKEND_PORT`).
pub const ENV_HOST_BACKEND_PORT: &str =
    concat!(env!("KINETIC_NETWORK_ID_UPPER"), "_HOST_BACKEND_PORT");
/// Environment variable string to override the backend proxy host IP (e.g. `KINETIC_MAINNET_HOST_BACKEND_HOST`).
pub const ENV_HOST_BACKEND_HOST: &str =
    concat!(env!("KINETIC_NETWORK_ID_UPPER"), "_HOST_BACKEND_HOST");
/// Environment variable string to override the governance state file path (e.g. `KINETIC_MAINNET_GOVERNANCE_PATH`).
pub const ENV_GOVERNANCE_PATH: &str =
    concat!(env!("KINETIC_NETWORK_ID_UPPER"), "_GOVERNANCE_PATH");

#[cfg(test)]
mod tests {
    use super::*;
    use sha2::{Digest, Sha256};

    #[test]
    fn test_production_root_key_fingerprint() {
        // We decode the hex production key and check its SHA-256 fingerprint.
        // This ensures the production key is NEVER accidentally changed without explicitly updating this test.
        let pub_bytes = hex::decode(prod_keys::ROOT_PUBLIC_KEY_HEX)
            .expect("Production root key must be valid hex");

        let mut hasher = Sha256::new();
        hasher.update(&pub_bytes);
        let hash = hasher.finalize();
        let hash_hex = hex::encode(hash);

        // The expected SHA-256 fingerprint of the officially generated ML-DSA-65 root key.
        let expected_fingerprint =
            "8b8b8ca511b8aec64accac035802a55f1674201eed1f8e54547a275af56124d7";

        assert_eq!(
            hash_hex, expected_fingerprint,
            "CRITICAL SECURITY ALERT: The production ROOT_PUBLIC_KEY_HEX does not match the expected SHA-256 fingerprint! Was the root key changed?"
        );
    }
}