Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help


crate: kinetic-core stage: 11 reading_time: 15 mins depends_on: [01_kyns.md, 10_governance_engine.md]

What Is This?

Kinetic’s governance isn’t just a configuration file or a loose set of admin scripts. It is a structured cryptographic state machine. This machine is resistant to quantum threats.

The types.rs and mod.rs files inside the kinetic-core governance module are critical. Coupled with their foundational counterparts in the kinetic-types crate, they construct the system. Specifically, they define the exact data structures required for executing privileged, network-wide actions.

These files lay out an exhaustive dictionary of what administrative actions are technically possible. Examples include granting 1-character premium domains, triggering emergency network halts, or permanently delegating root authority.

Furthermore, they establish precisely how these high-level Rust enums are encoded into flat canonical byte arrays. They define how they are cryptographically signed using ML-DSA-65 post-quantum signatures. Finally, they dictate how historical execution effects are persistently tracked on-disk across all active nodes.

Why Kinetic Needs This

For a distributed, decentralized, and sovereign network to remain secure, there must be absolute consensus. There must be zero ambiguity regarding how administrative commands are structured and authorized.

Without strongly typed governance actions (like the GovernanceAction enum), nodes might disagree on how to parse an emergency network halt packet. This would lead to chain splits.

Furthermore, Kinetic deliberately separates the strict serialization and deserialization of these actions. They are pushed into a completely isolated core crate (kinetic-types). Why? To allow offline, air-gapped signing tools to operate independently. Tools like hardware wallets, cold storage companion apps, or CLI utilities need to construct proposals. They need to mathematically verify governance proposals without compiling the entire network daemon’s dependency tree.

By strictly delineating intent, authorization, and state, Kinetic ensures security. Intent is what the action is. Authorization is who signed it and with what quantum-resistant keys. State is how the node remembers the execution history. This separation ensures that network governance remains deterministic, perfectly auditable, and secure.

How It Works

1. The Engine Variants (mod.rs)

-> See: kinetic-core/src/governance/mod.rs — Lines 6 to 16

Kinetic supports multiple, distinct governance models. These are fundamentally chosen at compile-time via the GOVERNANCE_MODEL flag. This flag is typically located in the deployment network.json.

  • sovereign: This represents the bootstrap or “dictator” phase. The designated Root key acts as a single-signer authority. If the Root signs the message, it bypasses all thresholds and executes instantly.
  • council: This is a threshold multi-signature voting system. It is designed for the decentralized phase of the network. In this model, at least 50% of an elected council’s members must cryptographically sign a proposal for it to pass.
  • permissionless: This mode strips away all cryptographic signing requirements. It exists purely for local testing and developer environments. Signature verification would just slow down iteration locally.

This abstraction means the underlying type system doesn’t have to change. Even as the live network migrates from a single founder to a decentralized committee, the structs remain identical.

2. The Two-Phase Commit Protocol

-> See: kinetic-core/src/governance/types.rs — Lines 7 to 12

Governance state changes in Kinetic do not happen magically or instantaneously. They follow a strict two-phase commit protocol.

First Phase (Proposal): A SignedGovernanceMessage is constructed and broadcast to the network. This packet acts as a pending “proposal.”

Second Phase (Execution): The active governance engine intercepts this message. It performs threshold verification on the signatures. If the signatures pass the cryptographic checks and meet the engine’s required threshold, it proceeds. The action is executed, producing a GovernanceEffect. This effect is then used to notify the rest of the node’s architecture.

3. Enumerating the Governance Actions

-> See: kinetic-types/src/governance.rs — Lines 30 to 69

Every single privileged action maps to a variant inside the GovernanceAction enum.

  • GrantPremiumName: Allows the root authority to mint a 1-character name. This name is granted directly to a specific user’s public key.
  • RevokePremiumName: Allows the root authority to revoke a premium name.
  • GrantInfrastructureName and RevokeInfrastructureName: Manages Category 2 infrastructure labels. Examples include “api”, “seed”, or “metrics”. This ensures only official nodes can bind to these protected namespaces.
  • RotateRootKey: Permanently delegates the root authority to a new ML-DSA-65 public key. This is a highly sensitive action used for disaster recovery or operational hand-offs.
  • EmergencyHalt: Used to forcefully pause all domain name registrations and renewals. This is invoked during catastrophic network bugs.
  • EmergencyResume: Lifts the emergency halt. It takes the number of kyns the network was paused for and appends it to the global state.

4. Canonical Byte Serialization

-> See: kinetic-types/src/governance.rs — Lines 82 to 154

To securely sign a proposal using a post-quantum algorithm, the types must be reduced to bytes. Kinetic uses a custom, highly deterministic “canonical” byte format. It avoids formats like JSON or MessagePack. Those libraries might reorder keys or pad bytes differently, invalidating the signature.

Inside the SignedGovernanceMessage::to_canonical_bytes() function, the payload is packed manually:

  1. The function pushes exactly 1-byte opcode representing the specific action. For example, 0x0A corresponds directly to granting a premium name.
  2. It packs variable-length data (like UTF-8 strings). It does this by first prefixing them with a 4-byte big-endian length header (u32).
  3. It appends fixed-length data directly to the buffer. For example, the 1952-byte ML-DSA-65 public keys.
  4. Finally, it always appends the proposal’s creation Unix timestamp. This is packed as an 8-byte big-endian u64 at the very end of the array.

This guarantees that an action will always resolve to the exact same bytes. This makes it safe to hash with SHA-256 and sign.

5. Post-Quantum Signature Verification

-> See: kinetic-core/src/governance/types.rs — Lines 24 to 37

Kinetic relies exclusively on post-quantum ML-DSA-65 signatures. The verify_signature utility function is the cryptographic gatekeeper.

It takes three arguments:

  • The raw bytes of the signer’s public key.
  • The canonical bytes of the message payload.
  • The raw bytes of the signature itself.

It uses the official ml_dsa Rust crate to deserialize the verifying key and the signature object. If parsing succeeds, it calls .verify(). Proposals cannot be forged because of these strict requirements.

6. Managing Time and Network Pauses

-> See: kinetic-core/src/governance/types.rs — Lines 77 to 117

When the network is forcibly halted via an EmergencyHalt action, “time” effectively stops. If a user paid for a 365-day domain name, and the network goes down for 7 days, they should not lose 7 days.

The GovernanceState struct tracks this phenomenon using pause_history. This is a vector containing tuples that mark the exact start and end “drand kyns”. These kyns represent the window during which the network was frozen.

The paused_kyns_since function calculates exactly how much “paused time” a registration gets. It iterates through the entire pause_history vector. It meticulously calculates the duration of pauses that occurred strictly after the target kyn.

7. Preventing Double-Granting Flaws

-> See: kinetic-core/src/governance/types.rs — Lines 120 to 191

The tests in types.rs highlight why the math in paused_kyns_since is so complex.

  • test_pause_history_double_granting_flaw: If a pause happens between kyn 1000 and 1100, but a user registers their name at kyn 2000… They should receive 0 paused kyns. They didn’t experience the outage.
  • test_pause_history_overlapping_pause: If a pause happens from kyn 1000 to 1100, and a user registers at kyn 1050… They should only be credited for the 50 kyns that occurred after their registration.

This meticulous edge-case handling ensures users are treated fairly. It prevents malicious actors from exploiting the system for free registration time.

8. Handling Execution Side Effects

-> See: kinetic-core/src/governance/types.rs — Lines 39 to 75

When a governance action successfully executes, it produces a GovernanceEffect. This is a lightweight enum used purely for internal node communication.

For example, if the root authority is rotated, the engine emits GovernanceEffect::RootKeyRotated. Other critical subsystems in the node listen for these effects via internal channels.

  • The p2p networking layer
  • The RPC API layer
  • The block production engine

When they receive the effect, they instantly update their local in-memory caches. This ensures the entire node pivots synchronously to respect the new state.

9. Governance Error Taxonomy

-> See: kinetic-types/src/governance.rs — Lines 157 to 219

Because governance payloads travel over the public internet, they can be manipulated. Parsing them must be incredibly defensive. GovernanceTypeError implements Kinetic’s standard, network-wide error taxonomy.

  • It maps BufferTooSmall to the deterministic code KIN-GOV-030.
  • It maps UnknownOpcode to KIN-GOV-031.
  • It maps InvalidUtf8 to KIN-GOV-032.

It explicitly sets is_retryable() to false. An invalid, corrupted payload will never miraculously become valid upon a retry. It also provides highly readable user_message strings. Block explorers and frontend dashboards can display exactly why a proposal was rejected.

Key Pieces

GovernanceAction

-> See: kinetic-types/src/governance.rs — Line 31 What it is: The central enum defining all permissible, privileged administrative actions. Why it matters: It strictly bounds the state space of what an administrator can actually do. If a desired command is not represented as a variant in this enum, it cannot be executed.

SignedGovernanceMessage

-> See: kinetic-types/src/governance.rs — Line 73 What it is: The outer envelope containing the internal action payload, timestamp, and signatures. Why it matters: This is the actual struct that travels over the wire via gossip protocols. It seamlessly bundles the administrative intent with the irrefutable cryptographic proof.

GovernanceState

-> See: kinetic-core/src/governance/types.rs — Line 79 What it is: The persistent on-disk database representation for the entire governance subsystem. Why it matters: It acts as the ultimate source of truth across restarts. It tracks the active root key, network halts, historical pauses, and executed hashes.

paused_kyns_since

-> See: kinetic-core/src/governance/types.rs — Line 100 What it is: A mathematical function calculating “forgiveness time” for domain names. Why it matters: Without this precise logic, a network outage would unfairly expire domains. This function protects innocent users from paying the price for infrastructure emergencies.

verify_signature

-> See: kinetic-core/src/governance/types.rs — Line 30 What it is: A robust wrapper around the ml_dsa crate for validating post-quantum signatures. Why it matters: It acts as the ultimate gatekeeper for governance operations. If this function evaluates to false, the proposal is instantly discarded as invalid.

to_canonical_bytes

-> See: kinetic-types/src/governance.rs — Line 103 What it is: A custom serialization implementation that reduces an enum to a flat byte array. Why it matters: Standard serializers (like serde_json) are not deterministic enough. By manually packing bytes, Kinetic ensures every node computes the exact same SHA-256 hash.

How This Connects to the Rest of Kinetic

CROSS-CRATE: The kinetic-core/src/governance/types.rs file heavily re-exports types. These types are natively defined in kinetic_types::governance. This intentional design pattern allows lightweight CLI signing tools to depend exclusively on kinetic-types. They can build and sign canonical byte slices without compiling the massive node software.

FORWARD DEPENDENCY: The actual, concrete execution of these types happens later down the line. It takes place in kinetic-core/src/governance/engine/. The engine takes the SignedGovernanceMessage, validates all the signatures against the thresholds, and mutates state.

CROSS-CRATE: The paused_kyns_since mathematical logic directly influences the Name Registry layer (kinetic-core/src/registry/). The registry must constantly consult the governance state. It uses this to calculate the true, adjusted expiration kyn of user domains.

Quick Reference

Governance Action Opcodes:

  • 0x0A - GrantPremiumName: Mint 1-char name.
  • 0x0B - RotateRootKey: Change network authority.
  • 0x0C - EmergencyHalt: Freeze registrations.
  • 0x0D - EmergencyResume: Unfreeze registrations.
  • 0x0E - RevokePremiumName: Remove 1-char name.
  • 0x0F - GrantInfrastructureName: Mint category 2 name.
  • 0x10 - RevokeInfrastructureName: Remove category 2 name.

Deterministic Serialization Rules:

  • Big-endian byte order is strictly enforced for all integers (u32, u64).
  • The specific action Opcode is always exactly 1 byte at the very start of the payload.
  • All variable-length fields (like strings) are preceded by a 4-byte u32 length header.
  • The proposal’s timestamp is universally appended to the extreme end of the payload buffer as an 8-byte u64.

Governance Effect Targets:

  • Networking Layer: Needs to know when the root key rotates to accept new commands.
  • RPC Layer: Needs to know when the network is halted to reject new HTTP requests.
  • Block Producer: Needs to know when premium names are granted to inject them into state.

Open Questions / Things to Revisit

  • Unbounded State Growth: The pause_history vector located inside the GovernanceState struct grows infinitely. If the network experiences thousands of micro-pauses over decades of operation, it could be bad. Iterating through this massive array for every single domain registration lookup could become a CPU bottleneck. We may need to investigate mechanisms to snapshot or compress historical pause records.

  • Council Implementation Details: While mod.rs clearly defines a council engine variant, the details are sparse here. The exact, low-level details of how a 50% threshold is configured requires more work. We need deeper exploration in the actual engine files to see how keys are added/removed.

  • Replay Protection Garbage Collection: The executed_hashes map fundamentally prevents old proposals from being maliciously replayed. However, it never currently drops old hashes. We need to implement a pruning strategy based on the proposal timestamp. This would avoid unbounded memory usage on disk, potentially rejecting any proposal older than a specific window.

  • Key Revocation Mechanics: The current implementation allows the root key to be rotated via action. But there isn’t a direct mechanism to handle compromised keys if the rotation itself is contested. The bounds of Sovereign mode might need emergency fallback protocols.