Crate: kinetic-core
Stage: 17
Reading Time: 20 minutes
Depends On: network_constants (network.json), types::names, constants
What Is This?
This file contains the core consensus mathematical formulas used by the Kinetic network. It primarily calculates the required physical computational time (Verifiable Delay Function iterations) needed to claim a name. Because Kinetic does not use a built-in cryptocurrency token for purchasing domains, it requires an alternative economic barrier. This module calculates two primary anti-abuse metrics:
- The VDF “Squatter Cliff” curve, which penalizes short names with massive iteration requirements.
- The “Steal Decay Math,” which uses an inverse-square formula to gracefully decay protective difficulty on abandoned names.
Why Kinetic Needs This
Kinetic aims to build a truly decentralized naming system where users own their identities without paying perpetual rent. However, in any system where domains are ostensibly “free,” the immediate threat is domain squatting. A malicious actor with automated bots could instantly claim every single short, recognizable name (like ai.kin, pay.kin, or x.kin). Traditional systems like ENS solve this by charging monetary fees or running auctions for short names. Kinetic solves this by requiring time. The Squatter Cliff uses exponential scaling rather than linear scaling. A linear scale would fail because it wouldn’t create a strong enough deterrent for a motivated attacker with a botnet. If we did not have the Squatter Cliff, a botnet could sweep up millions of short names in a matter of seconds. By enforcing the Squatter Cliff, we force the attacker to dedicate a massive amount of sequential processing power to just one single name. A 1-character name requires effectively 100 years of sequential VDF generation. This effectively makes 1-character names impossible to register via casual brute force. A 2-character name takes 30 days of 100% CPU time. A 3-character name takes 24 days of constant VDF generation. This creates a powerful economic disincentive for squatters and hoarders. Simultaneously, it leaves normal-length user names (like saifmukhtar.kin) at a manageable 30-minute baseline.
Furthermore, because there are no renewal fees in Kinetic, we face a critical “graveyard problem.” If a user loses their private key, dies, or a bot registers a name and abandons it, the name would be permanently locked forever. To solve this, Kinetic requires active name owners to periodically broadcast cryptographic “heartbeats.” When these heartbeats stop, the name officially enters an “idle” state on the network. We need a decentralized mechanism to recycle these idle names back into the public pool. The Steal Decay math is crucial because identity systems need to be fluid over decades. If someone registers a name but never uses it, the network considers it wasted space. However, we cannot just drop the shield instantly. A brief network outage or a power failure could cause a legitimate user to lose their valuable name. The Steal Decay Math provides a graceful degradation curve. Using an inverse-square curve, the difficulty to steal the name stays high for a very long time. The inverse square ensures it’s virtually impossible to steal a name that just went offline yesterday, protecting against temporary internet outages. Then, it dramatically drops down to the baseline difficulty once the target idle duration is reached. This strikes the perfect balance between protecting legitimate users during temporary outages and eventually recycling permanently abandoned names.
How It Works
The math in this module relies on the parameters injected into the constants.rs file. These constants are sourced directly from the network.json configuration file during the Rust build process. This strict injection ensures that every node on the Kinetic network agrees exactly on the math parameters.
1. The VDF Squatter Cliff Calculation
When a user attempts to register a new name, the node must determine exactly how many VDF iterations they must perform.
-> See: kinetic-core/src/consensus_math.rs — Lines 53 to 60 (required_iterations)
- Normalization: The function takes the raw string and normalizes it using IDNA conversions to handle unicode characters.
- TLD Stripping: It extracts the apex label by stripping the
.kinTop Level Domain (TLD). - Cheat Prevention: This stripping ensures that users cannot cheat the character count length by appending the TLD multiple times (e.g.
foo.kin.kin). - Dev Mode Bypass: If the node is currently running in development mode via
is_dev_mode(), the math is bypassed. -> See:kinetic-core/src/consensus_math.rs— Lines 66 to 68 - Fast Testing: It returns a very small, flat number of iterations (typically 1,000) purely so developers can test network logic without waiting 30 minutes.
- Hardware Baseline Calculation: The network possesses a global
BASE_ITERATIONSconstant. - Benchmarking: This represents a hardware anchor benchmark (the number of iterations a standard modern CPU can perform in 30 minutes).
- Time Normalization: It pulls the
TARGET_MINUTESconstant to normalize the calculation. - Length Matching: The core economic logic is executed via a
matchstatement on the exact string length of the extracted label (label.len()). -> See:kinetic-core/src/consensus_math.rs— Lines 78 to 91 - Character Count Independence: The squatter cliff curve is purely a function of the length of the string in characters.
- Unicode Support: It does not look at the bytes, meaning that emojis or other multibyte unicode characters are counted appropriately once normalized.
- Emoji Parity: This ensures a 1-emoji name is treated exactly the same as a 1-letter name.
- Multiplier Application: A closure named
calcis defined to multiply the baseline iterations by a specific factor. - Overflow Protection: The closure performs the math using
u128integers to prevent overflow, before safely casting back down tou64. - Length 0-1: Maps to a multiplier that equals 100 years of computation.
- Length 2: Maps to a multiplier corresponding to 30 days.
- Length 3: Maps to 24 days.
- Length 4: Maps to 15 days.
- Length 5-7: Rapidly drops from 1 day down to a few hours.
- Length 21+: Plummets to exactly
BASE_ITERATIONS. - Baseline Return: Any name 21 characters or longer takes the flat baseline of 30 minutes.
This engineered cliff penalizes ultra-short names while ensuring that regular user identities remain accessible.
2. The Inverse-Square Steal Decay Math
When a name already exists on the network, its owner must continuously send Drand-synchronized heartbeats. When they stop, the name enters an “idle” state, and the required VDF effort to take over this name begins to decay.
-> See: kinetic-core/src/consensus_math.rs — Lines 110 to 130 (steal_difficulty)
- Measuring Idleness: The network tracks idleness in terms of Drand “kyns” (the network’s fundamental unit of epoch time).
- Kyns Idle: The parameter
kyns_idleindicates exactly how many epochs the name has missed its heartbeat. - The Target Threshold:
steal_target_kynsdefines the exact point in time at which the difficulty multiplier should drop precisely to $1\times$. - Vulnerability Point: For example, if this is set to one year’s worth of kyns, the name is fully vulnerable after one year.
- The Inverse-Square Multiplier Formula: The formula compares the target kyns squared against the idle kyns squared:
(target_kyns / (kyns_idle + 1))^2. - Decay Shape: Because the relationship is squared, the difficulty drops very slowly at first, and then accelerates as it gets closer to the target.
- Halfway Attempt: If someone tries to steal a name when it is only halfway to the target idle time, the required VDF iterations are exactly $2^2 = 4$ times higher than the baseline effort.
- Early Attempt: If someone tries to steal it early, say at 1/10th of the target time, the effort is an $10^2 = 100$ times higher.
- Applying the Multiplier: The calculated multiplier is applied directly to the
base_iterationsargument. - Relative Baseline: Note that this
base_iterationsis NOT the network baseline; it is the specific baseline for that name calculated by the Squatter Cliff. - Persistent Cliff: This means an abandoned 2-character name still requires 30 days of effort even after the steal decay has fully run its course.
- Capping and Safety: The final mathematical result is capped at
u64::MAX. - Saturation Point: If an attacker tries to steal a name that just went offline 1 epoch ago, the math might output a number larger than a 64-bit integer can hold.
- Panic Prevention: Rather than panicking and crashing the node, it saturates at
u64::MAX, making the steal attempt impossible to complete before the universe ends.
Key Pieces
ConsensusParams (Struct)
-> See: kinetic-core/src/consensus_math.rs — Lines 21 to 24
What it does: This structure encapsulates the stateful configuration values required for all consensus math operations. Current State: Currently, it holds the steal_target_kyns value. Why it matters: It allows the mathematical functions to operate on stateful parameters rather than hardcoded global static variables. Testing Benefit: This dependency injection makes unit testing much easier. Mocking: Developers can instantiate a mock ConsensusParams struct with custom values to verify edge cases without needing to modify the global network configuration.
calculate_hardware_anchor()
-> See: kinetic-core/src/consensus_math.rs — Lines 36 to 38
What it does: This simple function returns the BASE_ITERATIONS constant, which is injected from the network constants file generated during the build. Why it matters: This serves as the fundamental anchor for all time-based proofs in the Kinetic network. Scaling Basis: It ensures that the squatter cliff multipliers are always scaling relative to the physical hardware benchmark. Security: If a rogue node operator manually lowers this constant in their local build, all of their generated VDF proofs will be rejected by the rest of the network.
required_iterations(name: &str)
-> See: kinetic-core/src/consensus_math.rs — Lines 53 to 60
What it does: This is the highest-level entry point used by the daemon. Normalization: It takes a raw string input, normalizes it into lowercase IDNA format, and strips out the Top Level Domain suffix. Why it matters: This ensures that users cannot manipulate the system. Case Safety: If they submit ExAmPlE.KiN, it is correctly normalized to example.kin. Length Safety: It also prevents the .kin suffix itself from counting towards the character length of the name, ensuring that a 3-character label is truly evaluated as 3 characters.
required_iterations_by_label(label: &str)
-> See: kinetic-core/src/consensus_math.rs — Lines 65 to 92
What it does: This function contains the actual Squatter Cliff math. Measurement: It measures the string length of the provided label and applies the corresponding massive multiplier to the network’s baseline iterations. Why it matters: This is the core economic engine of the network. Defense Mechanism: The multipliers used here (such as CONSENSUS_SQUATTER_LEN_2) are the primary defense mechanism preventing malicious botnets from draining the namespace.
steal_difficulty(base_iterations, kyns_idle)
-> See: kinetic-core/src/consensus_math.rs — Lines 110 to 130
What it does: This function calculates the inverse-square multiplier based on exactly how long a specific name has been dead (idle). Application: It applies this multiplier to the provided base_iterations argument. Why it matters: This provides a decentralized, enforced garbage collection system for the global namespace. Elegance: It solves the abandoned domain problem without relying on centralized registrars, auctions, or recurring monetary fees.
How This Connects to the Rest of Kinetic
FORWARD DEPENDENCY: Validation Engines The kinetic-core/src/validation module relies on these mathematical functions. When a node receives a Gossipsub message over the peer-to-peer network claiming a new name registration, it triggers validation. The validation engine will immediately call ConsensusParams::required_iterations for that name. It then checks if the VDF proof attached to the message actually performed that many iterations. If the proof is too short, the validation fails. The message is instantly dropped and the peer may be penalized for sending invalid data.
FORWARD DEPENDENCY: The VDF Prover & Client Daemon The kinetic-vdf crate and the client daemon use these math functions to figure out exactly how much work they need to do. They perform this check before they start solving the cryptographic puzzle. When a user runs a command to register a name, the client queries the daemon for the required iterations. The daemon calculates it using required_iterations. It warns the user if the registration will take 30 days to complete. Then it spins up the local VDF solver instructing it to execute exactly that many iterations.
CROSS-CRATE: Network Config Generation (build.rs) The multipliers and base iterations used throughout this file are not hardcoded in the Rust source code. They are dynamically generated by the build.rs script reading from the network.json configuration file at compile time. This architectural decision means that changing the Squatter Cliff curve is very easy. Adjusting the baseline difficulty for a new network fork does not require modifying consensus_math.rs directly. It only requires modifying the JSON config and recompiling the node software.
Quick Reference
- Base Iterations (
BASE_ITERATIONS): The absolute number of VDF iterations corresponding to the network’s target time benchmark. - Hardware Calibration: Usually calibrated to 30 minutes on modern consumer hardware.
- Squatter Cliff: The exponential curve penalizing short names.
- 1 Char Target: Impossible (Targeting 100 years of computation).
- 2 Chars Target: Targeting 30 days of computation.
- 21+ Chars Target: Targeting 30 minutes (Baseline).
- Steal Target Kyns (
STEAL_TARGET_KYNS): The precise duration (measured in Drand network epochs) that a name must be dead. - Decay Point: This is the point before the steal difficulty multiplier drops back down to $1\times$.
- Inverse-Square Decay: The specific mathematical formula that keeps steal difficulty high initially.
- Decay Landing: It decays rapidly as time goes on, eventually landing exactly at $1\times$ effort.
- Dev Mode Override: An override switch that flattens all mathematical requirements to a trivially small number of iterations (e.g., 1000) for rapid local development and testing.
Open Questions / Things to Revisit
- Integer Overflows in
calcClosure: Whilesteal_difficultysafely caps its output atu64::MAX, is there a risk incalc? - Absurd Multipliers: Is it possible that the
u128multiplication occurring during thecalcclosure in the Squatter Cliff could panic if someone configuresnetwork.jsonwith absurdly large custom multiplier numbers? - Safer Math: Using a
saturating_mulmight be a safer architectural choice than standard multiplication here. - Label Normalization Overhead: The
required_iterationsfunction actively allocates new strings during thenormalize_nameprocess. - DoS Vector Potential: Since this function is called inside the hot path during Gossipsub peer validation, could this become a Denial of Service (DoS) vector?
- Malformed Strings: A malicious peer could flood the node with massive, malformed unicode strings, causing constant heap allocations.
- Refactor Candidate: We might want to require that validation engines pass pre-normalized labels into this function to avoid redundant heap allocations.
- Hardware Drift Resilience: The documentation notes that hardware drift (computers getting faster over time) is handled manually via network updates.
- ASIC Threats: If specialized ASICs are developed for Kinetic’s specific VDF construction, the
BASE_ITERATIONSanchor will become obsolete. - Farming Short Names: This means 2-character short names will become farmable much faster than the intended 30 days.
- Dynamic Difficulty: Should Kinetic implement an automatic, dynamic difficulty adjustment algorithm (similar to Bitcoin’s retargeting) rather than relying on manual hard forks?
- Fractional Time Targets:
TARGET_MINUTESis defined as anf64float in the configuration file but is cast to au64inside thecalcclosure. - Loss of Precision: This cast loses all sub-minute precision.
- Divide by Zero Risk: If a developer sets
TARGET_MINUTESto0.5in a test network configuration, this will truncate to0, causing a divide-by-zero panic during execution. This should be patched to use floating point math for the division or enforce a minimum integer bound of1.