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

02 — Wasm Storage (Browser Extension Fallback)

Crate: kinetic-storage Stage: 4 of 10 Reading time: ~6 minutes Depends on: kinetic-core Source files: kinetic-storage/src/lib.rs (Lines 174 to 266)


What Is This?

This is the second half of the kinetic-storage crate. It provides an entirely in-memory, zero-disk Key-Value database that automatically replaces the sled database whenever the Kinetic codebase is compiled for a Web browser (WASM).


Why Kinetic Needs This

Important

The sled database requires direct access to a computer’s file system (hard drive). When Kinetic is compiled as a Wasm browser extension, it runs inside a strict security sandbox that physically cannot touch the host computer’s hard drive. If you try to compile sled to Wasm, the compiler will violently reject it. By using conditional compilation, Kinetic can ship the exact same node architecture to the browser without crashing the compiler.


How It Works

#![allow(unused)]
fn main() {
-> See: `kinetic-storage/src/lib.rs` — Lines 174 to 266
}

When the target_arch = "wasm32" compiler flag is active, the native module is ignored and this wasm module is activated. It creates a mocked SledStorage struct that looks exactly like the real one from the outside, but operates completely differently on the inside.

The Internal Engine (BTreeMap):

Instead of a database file, the data is stored in a RwLock<BTreeMap<Vec<u8>, Vec<u8>>>.

Note

-> See RUST_CONCEPTS.md for an explanation of BTreeMap and why it is used for fast prefix scanning.

Memory Constraints (DoS Protection):

#![allow(unused)]
fn main() {
-> See: `kinetic-storage/src/lib.rs` — Lines 240 to 242
}

Warning

Because this database lives entirely in RAM (memory), there is a severe risk of a browser tab crashing if the node downloads too much data. To prevent this, the put() function includes a hardcoded limit:

#![allow(unused)]
fn main() {
if db.len() >= 10_000 && !db.contains_key(key) {
    return Err(...);
}
}

If the database reaches 10,000 keys, it refuses to insert any new ones (though it allows updating existing keys).

Prefix Scanning:

#![allow(unused)]
fn main() {
-> See: `kinetic-storage/src/lib.rs` — Lines 218 to 229
}

Because a BTreeMap is naturally sorted, scanning for a prefix is extremely fast. The code uses db.range(prefix.to_vec()..) to instantly jump to the first key that matches the prefix, and then iterates forward. As soon as it hits a key that doesn’t start with the prefix, it breaks the loop early.


Key Pieces

#[cfg(target_arch = "wasm32")]

  • Location: lib.rs:174

Note

-> See RUST_CONCEPTS.md for an explanation of conditional compilation. This separates the browser build from the desktop build.

RwLock

  • Location: lib.rs:182

Note

-> See RUST_CONCEPTS.md for an explanation of RwLock<T>. This allows concurrent reads while safely locking for writes.


How This Connects to the Rest of Kinetic

  • CROSS-CRATE: This allows the entire kinetic-network P2P layer to run seamlessly in the browser. The networking code just calls storage.put(), completely unaware that it is writing to RAM instead of a hard drive.

Quick Reference

PropertyValue
WASM Engine:BTreeMap (In-memory).
Concurrency:Guarded by std::sync::RwLock.
Hard Limit:10,000 keys max to prevent browser OOM crashes.
Persistence:None. Wiped clean when the browser tab closes.

Open Questions / Things to Revisit

  • True Browser Persistence: Right now, the WASM storage is entirely ephemeral — all data is lost when the user closes the browser. For a real Kinetic wallet extension, this should ideally be upgraded to use the browser’s IndexedDB API (via web-sys) so that keys and peer tables survive tab closures. The 10,000 key limit is a stopgap for RAM exhaustion, but a persistent IndexedDB solution is the correct long-term architecture.