compiled to wasm32 Β· no bindgen
Three Rust projects,
running in this page.
A proof-of-work blockchain, a Redis client written from the wire protocol up, and a parallel computation CLI. Every demo below executes the actual crate source compiled to WebAssembly β not a JavaScript imitation of it.
Project 01 Β· consensus & cryptography
Blockchain-RUST
SHA-256 block sealing over a canonical length-prefixed encoding, a real nonce search against a difficulty target, and validation that re-derives every hash rather than trusting what is stored.
- sha2
- serde
- proof of work
- tamper detection
- no_std-friendly core
Mine a block
The nonce search below is the crateβs own mine_bounded, run in
short bursts so the page stays responsive while it works.
target β the hash must begin with 000
What exactly gets hashed
A blockβs hash has to be reproducible byte for byte, on any machine, in any order β otherwise two honest nodes derive different hashes from the same block and the chain forks for no reason. So the fields are fed to SHA-256 through a canonical length-prefixed encoding rather than any formatting the language happens to offer.
hasher.update(index.to_be_bytes()); hasher.update(timestamp.to_be_bytes()); hasher.update((transactions.len() as u64).to_be_bytes()); for tx in transactions { tx.hash_into(&mut hasher); // length-prefixed too } hasher.update((previous_hash.len() as u64).to_be_bytes()); hasher.update(previous_hash.as_bytes()); hasher.update(nonce.to_be_bytes()); // rendered as hex, so a difficulty target is // a plain string prefix comparison hex::encode(hasher.finalize()) // "0000b1d8ddf4f6cf3e27cb81β¦"
Length-prefixing is what makes it unambiguous: without it,
("ab", "c") and ("a", "bc") hash identically, and a
transaction could be rewritten without disturbing the digest. Validation
re-derives every hash from scratch rather than trusting the one stored in the
block β which is why the tamper button above gets caught.
Project 02 Β· network protocols
Redis-Client-RUST
A complete RESP2/RESP3 codec, correct stream framing over TCP, 40+ typed commands, pipelining and a bounded connection pool. No Redis crate is wrapped β the protocol is parsed here.
- tokio
- RESP2 / RESP3
- incremental decoder
- pipelining
- connection pool
Protocol explorer
Both panes call the crateβs real Command::encode and
resp::decode. The decoder is the same one the TCP client uses.
Encode a command
What the client puts on the wire.
Decode a frame
What comes back. Escapes: \r \n \xNN
Why the decoder returns Option
TCP has no message boundaries: one read may hand you half a
reply, or three replies at once. So decoding is incremental β
Ok(None) means βa valid prefix, send more bytesβ, and success
reports exactly how many bytes were consumed so the connection can drain
one frame and keep the rest.
pub fn decode(input: &[u8]) -> Result<Option<(Value, usize)>, ProtocolError> // Ok(Some((value, n))) one frame, n bytes consumed // Ok(None) incomplete, read more // Err(..) malformed or hostile
The test suite feeds every prefix of a multi-frame buffer through the decoder, so a split at any byte offset is proven to be handled. Try the partial preset above to see it.
Project 03 Β· parallelism & correctness
RUSTY-CLI
Parallel computation kernels with checked arithmetic, a Rayon work pool and a configuration layer where flags, files and defaults compose in a defined order.
- rayon
- clap
- checked arithmetic
- tokio
- indicatif
Where 32 bits run out
Drag past roughly 2,300 and the running total crosses u32::MAX.
The accumulator is a checked u64, so it keeps going β and stays exact.
sum > u32::MAX β 4,294,967,295
A u32 accumulator would wrap here, or panic in a debug build.
Every add is a checked_add on a u64, so the result
above is exact, and the limit is reported rather than hit.
Prime counting
Trial division over every integer below the limit β real CPU work, timed in your browser. Native builds run this across all cores with Rayon.
The bridge
Three crates, one module, no bindgen
The three projects are ordinary path dependencies of a small wasm crate, each built with its native-only features switched off. That is the whole trick: every core was written without I/O, so turning off Tokio, Rayon and the system clock leaves working code behind.
Building it yourself
Each project is a standalone crate with its own suite. Nothing here is checked in without passing all three.
# each of the three projects cargo test cargo clippy --all-targets -- -D warnings cargo fmt --all -- --check # the wasm that powers this page cargo build --lib --no-default-features \ --target wasm32-unknown-unknown