röyksopp | Update
Jan 17, 2026
It started as an OTP-flavored actor runtime with a toy TCP mesh, and now it has a minimal blockchain node layered on top.
TL;DR
- Added a minimal blockchain pipeline with persistence, mempool rules, and round-robin consensus.
- Introduced compact block propagation and batched sync.
- Added CLI tools and scripts to spin up a local cluster and play with it.
- Expanded docs, tests, and fuzzing so the system is easier to reason about.
What changed
Persistence and recovery
- BlockStore is still append-only, but the StateStore now uses snapshot + WAL (write-ahead log).
- On startup, state can recover by replaying the WAL and verifying against the block store tip.
- This gives a simple durability story without a full DB.
Mempool rules
- Mempool now validates txs:
- size limit
- minimum fee
- duplicate detection
- Ordering is fee-first when assembling blocks.
Txnow includes afeefield and stableidhash.
Consensus hardening
- Consensus is still round-robin leader, but now includes view timeouts.
- A node bumps its view when it times out and broadcasts a
ViewChange. - Blocks include the view in the header.
Block propagation
- Added compact block announcements:
- Nodes announce headers + tx IDs.
- Peers reconstruct if they already have the txs.
- Otherwise they fetch the full block by height.
- Added batched block sync to reduce RPC chatter.
Tooling and scripts
CLI binaries
royksopp- run a node from config.royksopp_keys- generate/read keypair and print pubkey hex.royksopp_play- interactive playground (local or attached).
Scripts
scripts/run_nodes.sh- spin up N nodes and write configs/logs.scripts/play.sh- interactive client (in-process by default).scripts/demo.sh- full demo: start nodes + attach client.
Make targets
API usage
In-process submission:
let tx = Tx ;
runtime.chain.submit_tx.await?;
RPC submission:
let req = SubmitTx ;
let bytes = serialize?;
let resp_bytes = net.request.await?;
Wire protocol (short version)
- All frames are length-delimited and bincode-encoded.
- Envelope:
version,chain_id,msg_type,request_id,payload. Helloincludes ed25519 signature over version/chain_id/id/listen/pubkey.- Chain RPCs:
GetTip,GetBlock,GetBlocks,SubmitTx
Documentation refresh
README.md now includes:
- Architecture overview
- Wire protocol details
- Config schema and defaults
- API examples
- Scripts and CLI usage
Tradeoffs / limitations
- No tx signatures or account model.
- No fork choice beyond round-robin + view timeouts.
- Mempool is in-memory only.
- Transport is authenticated but not encrypted.
If you want to try it
The easiest path:
Then use the interactive prompt:
key=value [fee]
tip
exit
What I want to do next
- Persistent mempool + eviction
- Snapshot/restore tools
- Peer scoring + backoff
- Transport encryption + message signing