{"id":51564123,"url":"https://github.com/arcsymer/restos-ledger","last_synced_at":"2026-07-10T13:04:03.969Z","repository":{"id":369820300,"uuid":"1291713831","full_name":"arcsymer/restos-ledger","owner":"arcsymer","description":"Raft-replicated append-only KV ledger in C++20 — deterministic consensus core, TCP cluster, tested under ASan/TSan","archived":false,"fork":false,"pushed_at":"2026-07-07T04:11:17.000Z","size":26,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-07T06:09:31.935Z","etag":null,"topics":["cmake","consensus","cpp","cpp20","distributed-systems","googletest","portfolio","raft","sanitizers"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arcsymer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-07T03:26:34.000Z","updated_at":"2026-07-07T04:09:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/arcsymer/restos-ledger","commit_stats":null,"previous_names":["arcsymer/restos-ledger"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/arcsymer/restos-ledger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsymer%2Frestos-ledger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsymer%2Frestos-ledger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsymer%2Frestos-ledger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsymer%2Frestos-ledger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arcsymer","download_url":"https://codeload.github.com/arcsymer/restos-ledger/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arcsymer%2Frestos-ledger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35331985,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-10T02:00:06.465Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmake","consensus","cpp","cpp20","distributed-systems","googletest","portfolio","raft","sanitizers"],"created_at":"2026-07-10T13:04:03.409Z","updated_at":"2026-07-10T13:04:03.960Z","avatar_url":"https://github.com/arcsymer.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# restos-ledger\n\nA Raft-replicated, append-only ledger with a key-value state machine, written in modern C++20 —\nthe durable, crash-safe log that would sit behind the RestOS restaurant system (orders, stock\nmoves). The consensus core is pure logic driven by an injected clock and message bus, so it's\ntested deterministically; a thin TCP layer runs it as a real multi-node cluster.\n\n![C++20](https://img.shields.io/badge/C%2B%2B-20-00599C?logo=cplusplus\u0026logoColor=white)\n![CMake](https://img.shields.io/badge/CMake-3.20%2B-064F8C?logo=cmake\u0026logoColor=white)\n![Sanitizers](https://img.shields.io/badge/CI-ASan%20%2B%20TSan-8A2BE2)\n[![ci](https://github.com/arcsymer/restos-ledger/actions/workflows/ci.yml/badge.svg)](https://github.com/arcsymer/restos-ledger/actions/workflows/ci.yml)\n![License: MIT](https://img.shields.io/badge/license-MIT-green)\n\nDemo evidence: [docs/demo.md](docs/demo.md) — a real 3-node cluster committing writes over TCP.\n\n## Quickstart\n\nPrerequisites: a **C++20 compiler** (GCC 12+/Clang 15+/MSVC 2022), **CMake 3.20+**, and a\ngenerator (**Ninja** recommended, or Make). GoogleTest is fetched automatically. Nothing else —\nno accounts, no services.\n\n```sh\ngit clone https://github.com/arcsymer/restos-ledger \u0026\u0026 cd restos-ledger\ncmake -S . -B build -G Ninja        # omit -G Ninja to use your default generator\ncmake --build build\nctest --test-dir build --output-on-failure   # 8 tests: election, replication, crash-restart, …\n```\n\nRun a real 3-node cluster and talk to it:\n\n```sh\nscripts/cluster.sh                  # Windows: scripts\\cluster.ps1   (boots ports 5000-5002)\nbuild/restos-cli --nodes 127.0.0.1:5000,127.0.0.1:5001,127.0.0.1:5002 put order:42 \"2x zurek\"\nbuild/restos-cli --nodes 127.0.0.1:5000,127.0.0.1:5001,127.0.0.1:5002 get order:42\n```\n\n\u003e On Windows the binaries are `restos-cli.exe` / `restos-node.exe`. Git Bash appends `.exe`\n\u003e automatically; in PowerShell/cmd write `build\\restos-cli.exe`.\n\n## Architecture\n\n```mermaid\nflowchart LR\n    subgraph core[restos_core — pure logic, no I/O]\n      RN[RaftNode\\nrole · term · log · commitIndex] --\u003e|apply committed| KV[(KV state machine)]\n      RN --\u003e|persist| LS[(LogStore\\nbinary file + fsync)]\n    end\n    RN --\u003e|RequestVote / AppendEntries| T{Transport}\n    T --\u003e|tests| SIM[SimCluster\\nin-process bus + manual clock]\n    T --\u003e|demo| TCP[TcpTransport\\nWinsock / POSIX]\n    CLI[restos-cli\\nput / get] --\u003e|length-prefixed TCP| NODE[restos-node × 3]\n```\n\nThe Raft node never touches a socket or the wall clock — time comes from `tick(now_ms)` and\nmessages from `receive()`. That's what makes it deterministically testable; the TCP transport and\nthe CLI are a thin shell around the same core.\n\n## Features\n\n1. **Append-only log + KV state machine** — binary on-disk format; `put`/`del` applied from\n   committed entries; `currentTerm`, `votedFor`, and `commitIndex` persisted (crash-safe).\n2. **Leader election** — terms, `RequestVote`, randomized timeouts, step-down on a higher term.\n3. **Log replication** — `AppendEntries` with log-matching + conflict truncation; commit by\n   majority; apply to the state machine.\n4. **Deterministic simulation harness** — an in-process bus + manual clock (`SimCluster`) with\n   crash/partition injection: the substrate for the consensus tests.\n5. **TCP transport + 3-node cluster** — length-prefixed framing over Winsock/POSIX sockets;\n   `scripts/cluster.{sh,ps1}` boot a local cluster.\n6. **CLI client** — `restos-cli put/get`, following the leader via a REDIRECT hint.\n7. **Tested + sanitized** — 8 GoogleTest cases; CI builds with **GCC and Clang**, runs the suite\n   under **AddressSanitizer and ThreadSanitizer**, enforces a **-Werror** warning-clean build,\n   and includes a **Windows MinGW** job + gitleaks.\n\n## Testing \u0026 CI\n\n```sh\nctest --test-dir build --output-on-failure           # the suite\ncmake -S . -B asan -DRESTOS_SANITIZE=ON \u0026\u0026 cmake --build asan \u0026\u0026 ctest --test-dir asan   # ASan\ncmake -S . -B tsan -DRESTOS_TSAN=ON \u0026\u0026 cmake --build tsan \u0026\u0026 ctest --test-dir tsan       # TSan\n```\n\n## Limitations\n\n- **MVP Raft:** no log snapshotting/compaction and no dynamic membership changes (both v2). Reads\n  are served by the leader; there's no lease-based read optimization.\n- **Single-threaded node:** the demo server uses one `select()` loop with blocking peer connects,\n  so a peer that is *hung* (not cleanly down) can briefly stall it — fine for a local demo, but a\n  production node would use non-blocking peer I/O (v2). Fault-tolerance/safety properties are\n  proven by the deterministic tests, not by racing real sockets.\n- Synthetic, single-cluster, local only; the on-disk format is host-endian (per-node local).\n\n## v2 ideas\n\nSnapshotting + compaction; dynamic membership; pre-vote; leadership-lease reads; non-blocking\npeer I/O; a mmap-backed log.\n\n## License \u0026 attribution\n\nMIT — see [LICENSE](LICENSE). Part of the [RestOS](https://github.com/arcsymer) portfolio.\n\nBuilt end-to-end with an agentic workflow (Claude Code), orchestrated, reviewed, and directed by me.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcsymer%2Frestos-ledger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farcsymer%2Frestos-ledger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farcsymer%2Frestos-ledger/lists"}