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

Kinetic: Rust Concepts Glossary

This document serves as a centralized glossary for all the high-level, advanced Rust concepts used extensively throughout the entire Kinetic monorepo (core, network, daemon, node, host, cli, vdf, dns, pac, etc.).

By centralizing these concepts, we avoid documenting the same pattern redundantly across every crate.


1. Concurrency, Async, and Threading

tokio::spawn and tokio::task::spawn_blocking

#![allow(unused)]
fn main() {
// Launch async task
tokio::spawn(async move { handle_request().await; });

// Offload heavy CPU math
tokio::task::spawn_blocking(move || { compute_vdf() }).await;
}
  • What it is: tokio::spawn launches an asynchronous background task on the Tokio runtime, allowing highly concurrent I/O operations (like handling hundreds of HTTP requests). spawn_blocking offloads heavy, CPU-bound computations (like VDF generation, PoW hashing, or disk I/O) to a dedicated OS thread pool.
  • How Kinetic uses it: The kinetic-daemon and kinetic-cli use spawn_blocking extensively for cryptographic tasks. If this math were run on the normal async thread, it would starve the executor and drop incoming network packets.
  • WASM Equivalent: In kinetic-wasm, standard Tokio threading is unsupported. wasm_bindgen_futures::spawn_local is used instead to bridge Rust’s async futures with the browser’s native JavaScript microtask queue.

Note

Standard Tokio threading is unsupported in WebAssembly. Always use wasm_bindgen_futures::spawn_local for WASM targets.

std::sync::Mutex vs tokio::sync::Mutex vs RwLock<T>

TypeThread BlockingBest Use CaseReaders/Writers
std::sync::MutexBlocks OS ThreadUltra-fast updates, no .await1 Writer OR 1 Reader
tokio::sync::MutexYields to RuntimeHeld across .await points1 Writer OR 1 Reader
RwLock<T>Thread BlockingRead-heavy workloadsInfinite Readers OR 1 Writer
  • What they are: Synchronization primitives that safely lock data for multi-threaded access.
  • How Kinetic uses them:
    • std::sync::Mutex is used for ultra-fast, synchronous updates where the lock is never held across an .await point.
    • tokio::sync::Mutex safely yields execution back to the runtime while waiting, which is required if the lock is held across network calls.
    • RwLock (Read-Write Lock) allows infinite simultaneous readers but only one writer. It is used heavily in kinetic-host and kinetic-dns (e.g., caching upstream resolvers) because reads happen thousands of times per second, but writes (config reloads) are rare.

Asynchronous Channels (mpsc, oneshot, broadcast, watch)

  • What they are: Thread-safe queues for passing messages between tasks.
  • How Kinetic uses them:
    • mpsc (Multi-Producer, Single-Consumer): Used to funnel API commands from multiple HTTP threads into the single-threaded Libp2p swarm event loop.
    • oneshot: Bundled inside the mpsc commands to route the exact network response back to the specific foreground API thread that requested it.
    • broadcast: Fans out identical messages (like Gossipsub events) to multiple consumers, such as live SSE streams.
    • watch: Retains only the latest value (like the current_drand_kyn epoch), dropping outdated state instantly so observers never process stale data.

tokio::select! and tokio::join!

#![allow(unused)]
fn main() {
tokio::select! {
    _ = sigterm.recv() => { println!("Shutting down"); }
    packet = socket.recv() => { process(packet); }
}
}
  • What they are: Macros for managing multiple asynchronous futures concurrently.
  • How Kinetic uses them: select! races multiple branches and executes the first one that completes (e.g., racing incoming network packets against a graceful shutdown SIGTERM signal). join! waits for all branches to finish concurrently.

tokio::sync::Semaphore

  • What it is: Limits how many tasks can access a resource simultaneously.
  • How Kinetic uses it: The try_acquire_owned() method acts as a non-blocking rate limiter for gossip messages and VDF evaluations, instantly dropping packets during DDoS attacks instead of halting the executor or exhausting RAM.

std::sync::atomic::AtomicU64

  • What it is: A variable that can be safely mutated across threads at the hardware level without a Mutex.
  • How Kinetic uses it: Used in kinetic-storage to cleanly track database corruption fallback counters without risking deadlocks during panic handling.

2. Memory, Pointers, and Data Types

Box<T> and Arc<dyn Trait> (Dynamic Dispatch)

  • What they are: Heap allocations. Box owns the data. Arc (Atomically Reference Counted) safely shares read-only ownership across multiple threads. dyn Trait hides the concrete type behind a standard interface.
  • How Kinetic uses them: NameRecord::Standard uses Box<Reveal> to prevent the massive Reveal struct from bloating the entire enum’s memory footprint. Arc<dyn VdfEngine> allows the daemon to hot-swap cryptographic engines at runtime without altering the networking code.

&[u8] vs Vec<u8> vs bytes::Bytes

TypeMemory LocationMutabilityOwnershipBest Use Case
&[u8]Pointer to memoryRead-onlyBorrowedCryptographic validation (Zero-copy)
Vec<u8>HeapMutableOwnedBuilding network payloads
bytes::BytesHeap (Ref-Counted)Read-onlyShared OwnershipPassing multi-megabyte streams through pipelines
  • What they are: Different ways to interact with byte arrays in memory.
  • How Kinetic uses them: Kinetic returns &[u8] for cryptographic validations (like checking signatures) to avoid memory allocation overhead. It uses bytes::Bytes in the HTTP proxy to pass multi-megabyte video streams through the pipeline by just incrementing a tiny pointer counter, preventing massive RAM duplication.

Cow<'_, T> (Clone-On-Write)

  • What it is: A smart pointer that holds either borrowed references (fast) or owned data (slow).
  • How Kinetic uses it: In kinetic-network, the record store returns a cheap reference for reads, but dynamically allocates a copy only if the data needs mutation.

Option<T> and Result<T, E>

  • What they are: Rust’s zero-cost replacements for null and Exceptions.
  • How Kinetic uses them: Option forces the compiler to ensure code explicitly handles missing data (like an optional manifest signature). Result safely propagates errors. E.g., Result<Option<T>, E> rigorously maps three states: invalid, missing, or present.

Specialized Collections (BTreeMap, LruCache, HashMap)

  • What they are: Highly optimized data structures.
  • How Kinetic uses them:
    • HashMap provides O(1) lookups for DNS zones.
    • BTreeMap keeps keys sorted, enabling blazing-fast scan_prefix operations for the WASM fallback database.
    • lru::LruCache ejects the Least Recently Used elements, preventing RAM exhaustion from malicious peers overflowing the banned peer list.

3. Macros and Code Generation

thiserror (#[error], #[from], #[source])

  • What it is: An external macro that auto-generates error trait implementations.
  • How Kinetic uses it: Removes hundreds of lines of boilerplate. #[from] allows automatic conversion of system errors (like std::io::Error) into unified KineticError variants via the ? operator.

serde (#[serde(untagged)], #[serde(tag = ...)], #[serde(other)])

  • What it is: Directives for parsing JSON and binary structures.
  • How Kinetic uses it:
    • untagged allows seamless wire transmission of different payload variants without bloated "type" JSON keys.
    • other safely catches unrecognized DNS records sent by future protocol versions without crashing the parser.

#[cfg(...)] and #![no_std] (Conditional Compilation)

#![allow(unused)]
fn main() {
#[cfg(not(target_arch = "wasm32"))]
pub mod native_db;

#[cfg(target_arch = "wasm32")]
pub mod wasm_db;
}
  • What it is: Tells the compiler to include or exclude code based on the target environment.
  • How Kinetic uses it: #[cfg(not(target_arch = "wasm32"))] strips out native Sled database I/O when compiling for browsers. #![no_std] ensures the kyn-vdf core cryptographic math can compile without an operating system.

Important

#![no_std] is an absolute requirement for compiling the pure-Rust cryptographic math into secure WebAssembly environments.

proptest!

  • What it is: A property-based fuzzer.
  • How Kinetic uses it: Generates thousands of randomized, hostile byte arrays to test the DNS parser in kinetic-dns, ensuring it cannot panic regardless of malicious inputs.

4. Systems, Safety, and Advanced Syntax

Filesystem Locks & Atomic Writes

  • What it is: Safe interaction with the host OS.
  • How Kinetic uses it: fs2 uses OS-level flock to ensure only one VDF process runs per machine, preventing cross-daemon CPU saturation. When writing config files (like PAC scripts), Kinetic writes to a .tmp file and calls std::fs::rename() to atomically replace the old file, guaranteeing zero corruption if power is lost mid-write.

Constant-Time Equality (subtle::ConstantTimeEq)

  • What it is: A mathematical comparison that always takes the exact same number of CPU cycles.
  • How Kinetic uses it: Prevents cryptographic timing attacks on the API. Without it, an attacker could guess an API Bearer token character-by-character by measuring microsecond variations in how fast the server rejects the request.

Warning

Never use standard == string comparisons for API tokens. Always use ConstantTimeEq to prevent microsecond timing attacks.

std::process::Command (Process Delegation)

  • What it is: Shells out to execute external OS processes.
  • How Kinetic uses it: kinetic-cli acts as a unified delegator. Instead of running networking code directly, it executes commands like sudo kinetic-dns start and streams the output directly to the user’s terminal.

Extension Trait Pattern

  • What it is: Bypasses Rust’s “Orphan Rule” (which forbids implementing standard methods on external types).
  • How Kinetic uses it: Kinetic creates custom traits (like DnsZoneExt) to bolt heavy validation logic (parse_payload) onto lightweight structs provided by third-party libraries (like hickory-dns).

Differential Fuzzing in Cryptography

  • What it is: Testing two entirely different implementations against each other instead of static answers.
  • How Kinetic uses it: kinetic-vdf tests the pure Rust verification logic (kyn-vdf) against the C++ FFI library (chiavdf) with millions of random inputs, ensuring absolute mathematical parity to prevent network forks.

PhantomData and the Newtype Pattern

  • What it is: Zero-overhead type system strictness.
  • How Kinetic uses it: KineticDid wraps a String privately. The only way to instantiate it is via a constructor that validates the syntax. Thus, any function accepting a KineticDid knows with 100% certainty the DID is valid without ever re-running validation checks.