db-18 — Execution

One-shot: prove it works

cd db-18-paxos
bash scripts/verify.sh        # all three languages' unit tests
bash scripts/cross_test.sh    # 6 scenarios × 3 binaries × byte-identical hash

verify.sh must end with === verify OK ===. cross_test.sh must end with === ALL OK === and the six per-scenario hashes must match the table in docs/observation.md.

Per-language workflows

Rust

cd src/rust
cargo build --release         # builds paxos18 lib + paxosctl bin
cargo test --release          # 12 unit tests (see verification.md)
./target/release/paxosctl --seed 42 --nodes 3 --rounds 1000 --proposals 5

Crate layout:

  • src/lib.rspaxos18 library: ballot, RPCs, PaxosNode, Cluster, canonical dump, sha256 helper, inline #[cfg(test)] module.
  • src/bin/paxosctl.rs — CLI entry: parses flags, runs the cluster, emits the sha256 hex digest on a single line with no newline.

Go

cd src/go
go build ./...                # builds package + cmd/paxosctl
go test ./...                 # 11 unit tests
./paxosctl_bin --seed 42 --nodes 3 --rounds 1000 --proposals 5

Module layout:

  • paxos.go — package db18: same surface as the Rust crate.
  • paxos_test.gogo test suite.
  • cmd/paxosctl/main.go — CLI binary.
  • go.mod — module github.com/10xdev/dse/db18, go 1.22.

C++

cd src/cpp
mkdir -p build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j
./test_db18                   # 11 unit tests
./paxosctl --seed 42 --nodes 3 --rounds 1000 --proposals 5

Source layout:

  • include/db18/paxos.hpp + src/paxos.cpp — the db18 namespace library.
  • src/paxosctl_main.cpp — CLI entry.
  • tests/test_db18.cpp — gtest-style assertions (no framework dependency; pure asserts + main).
  • CMakeLists.txt — exposes db18_lib, paxosctl, test_db18.

CLI reference

paxosctl has the same flags in all three languages. Anything else on the command line is rejected.

FlagTypeDefaultMeaning
--seedu64requiredSeeds splitmix64 for the cluster, every node's election jitter, and every message's delivery delay.
--nodesu32 (1..=8)requiredNumber of acceptor/proposer nodes; quorum = nodes/2 + 1.
--roundsu64requiredNumber of sim-time ticks to run.
--proposalsu32requiredNumber of client values to inject. Value i is "val-{i}", scheduled at tick (i+1)*rounds/(proposals+1).
--partitioncomma list of src,dst pairs (even-length)(none)Drop every message with the listed (src, dst) ordered pairs. Asymmetric: 0,1 blocks 0→1 but not 1→0. Pass 0,1,1,0 for a symmetric link cut.

Output: a single line of lowercase hex (64 chars), no trailing newline. Exit code 0 on success; non-zero with a stderr message on parse error.

Sample invocations

# Single-node "consensus" — leader is itself, every proposal decides instantly.
paxosctl --seed 1 --nodes 1 --rounds 200 --proposals 5

# Three-node happy path.
paxosctl --seed 42 --nodes 3 --rounds 1000 --proposals 5

# Symmetric partition between 0 and 1 plus 0 and 2 — node 0 is isolated.
paxosctl --seed 42 --nodes 3 --rounds 1000 --proposals 3 \
  --partition 0,1,0,2,1,0,2,0

Canonical scenarios

These are the six configurations that cross_test.sh runs. Each combination is a known-stable byte fingerprint; if any of them changes, you have changed semantics and should expect the cross-test to fail until you understand why.

NameFlagsNotes
A--seed 42 --nodes 3 --rounds 1000 --proposals 5happy path, 3-node, no partition
B--seed 7 --nodes 5 --rounds 2000 --proposals 205-node, longer schedule, more decisions
C--seed 99 --nodes 3 --rounds 500 --proposals 0leader election only; no proposals
D--seed 1 --nodes 1 --rounds 200 --proposals 5single-node; quorum = self
E--seed 42 --nodes 3 --rounds 1000 --proposals 3 --partition 0,1,0,2,1,0,2,0node 0 isolated symmetrically; {1,2} retain quorum
F--seed 3 --nodes 5 --rounds 1500 --proposals 10 --partition 0,1asymmetric link cut; minor degradation

Sanity checks

If you only have ten seconds:

( cd src/rust && cargo build --release ) >/dev/null && \
( cd src/go && go build -o paxosctl_bin ./cmd/paxosctl ) >/dev/null && \
( cd src/cpp/build && cmake --build . --target paxosctl ) >/dev/null && \
diff <(src/rust/target/release/paxosctl --seed 42 --nodes 3 --rounds 1000 --proposals 5) \
     <(src/go/paxosctl_bin            --seed 42 --nodes 3 --rounds 1000 --proposals 5) && \
diff <(src/rust/target/release/paxosctl --seed 42 --nodes 3 --rounds 1000 --proposals 5) \
     <(src/cpp/build/paxosctl         --seed 42 --nodes 3 --rounds 1000 --proposals 5) && \
echo OK

Silence + OK = green. Any diff = divergence; jump to docs/observation.md § Divergence runbook.