experiment combining verus with simulation testing of simple CASPaxos implementation
Install Verus from https://github.com/verus-lang/verus/releases and put the binary on your PATH, or note its location.
# Verify all five spec layers + exec-layer ghost instrumentation
verus --crate-type lib src/lib.rsExpected output:
verification results:: 39 verified, 0 errors
The verified items span:
- Layer 1 (
primitives.rs) — ballot ordering, quorum intersection,apply_casversion increment - Layer 2 (
acceptor.rs) —inv_acceptorpreservation through prepare/accept,select_valueversion maximality;handle_prepareensuresPromise.accepted == pre-call state.accepted(no assume) - Layer 3 (
quorum.rs) — single-value-per-ballot agreement, cross-ballot version uniqueness viainv_chosen_in_history; thephase1_responsesaxiom is deleted and replaced by a concretepromises: Seq<Promise<S>>parameter with a caller-proved completeness precondition - Layer 4 (
history.rs) —ChosenHistorymonotonicity and causal chain preserved under append; bridge invariantinv_chosen_in_historyconnects snapshotchosento history;CommitTimestampstype for time-index correspondence - Layer 5 (
linearizability.rs) — full linearizability capstone with three closed sub-proofs (version-serialization consistency, write linearization, time-index correspondence) — noassumein body - Exec layer (
cluster.rs) — type-unified with spec types;CASPaxosClusterstruct carries ghost fields (ghost_states,ghost_history,commit_timestamps,logical_clock);inv()spec predicate maintained throughnew()(proved) and tracked throughrun_proposalwith Phase 1 and Phase 2 ghost instrumentation
Spec-layer assumes: zero. All four original safety-bearing assume(...) calls are closed:
assume(false)axiom inquorum.rs— replaced by concrete ghost tracking- 2x
assume(v1 == v2)inquorum.rs— replaced byinv_chosen_in_history+inv_history_monotone assume(is_valid_linearization(...))inlinearizability.rs— replaced by three sub-proofs
Exec-layer structural admits (all in proof {} blocks, erased at runtime):
assume(inv_acceptor(old_state))x2 — the execHashMap<NodeId, AcceptorState<S>>lacks a Verus-verified spec; the assumes are sound because all states enter the map throughhandle_prepare/handle_acceptwhich proveinv_acceptorpreservationassume(nv_clone == new_value)— Verus has no clone spec for genericS; sound becauseClonefor structs preserves field values- Several ghost-tracking preconditions for history extension lemmas (universe membership, version monotone, alternate-chosen preservation) — honest structural limitations of the ghost tracking scope
cargo runRuns three scenarios:
- Happy path — 5 acceptors, sequential proposals, version monotonicity and UUID distinctness asserted
- Minority failure — 2 of 5 nodes fail-stopped, quorum of 3 still commits
- Contention storm — 20% message drop rate, 5 concurrent proposers, all invariants hold
cargo test