The concrete building blocks of REF's TLA+ specifications. What parameters are fixed, what state TLC explores, and what transitions define the protocol's behavior — sourced directly from the verified artifacts.
Constants define the boundaries of the state space TLC explores. They are fixed before each run — different values produce different verification scopes.
Variables define the state space. TLC exhaustively explores every reachable combination of variable values, checking invariants at each state.
Every action has a guard (precondition) and an effect (state mutation). TLC fires all enabled actions nondeterministically at each state, building the complete reachable state graph. Click any action to expand its guard and effect.
v ∈ Honest
v is leader for (height[v], view[v])
No existing proposal from v at this (h,v)
Create proposal record
Broadcast to all validators
Cast own PREPARE vote
v ∈ Honest
Proposal exists for (height[v], view[v])
v has not yet voted PREPARE for this (h,v)
Add PREPARE vote to prepareVotes
Vote references existing proposal value
v ∈ Honest
Quorum of matching PREPARE votes exists for value val
lockedView[v] < current view
lockedValue[v] ← val
lockedView[v] ← current view
highestQC[v] ← new QC record
v ∈ Honest
v is locked on a value
v has not yet COMMIT-voted at this (h,v)
Add COMMIT vote to commitVotes
Vote references lockedValue[v]
v ∈ Honest
Quorum of matching COMMIT votes exists
decision[v] = NIL (not yet decided)
decision[v] ← committed value
Add to decided set
Advance height
These actions model adversarial behavior. The Byzantine validator (v4) can equivocate, vote for conflicting values, and attempt to break safety. The invariants must hold despite these actions firing.
Proposer ∈ Byzantine
Can propose ANY value (including conflicts)
Propose conflicting values to different subsets
Stutter guard: proposal ∉ existing proposals
Voter ∈ Byzantine
References an existing proposal
Vote ∉ prepareVotes (stutter prevention)
Cast PREPARE vote for any existing proposal
Can vote for conflicting values at same (h,v)
Voter ∈ Byzantine
References an existing proposal
Vote ∉ commitVotes (stutter prevention)
Cast COMMIT vote for any existing proposal
Can commit to conflicting values
p ∈ Purchases
p ∉ purchases (not already registered)
purchases' = purchases ∪ {p}
p ∈ purchases
tokens[p] = ⊥ (no token exists)
n ∈ Nullifiers \ used nullifiers
tokens'[p] = [nullifier ↦ n, status ↦ ISSUED]
Enforces AtMostOneTokenPerPurchase
tokens[p].status = ISSUED
tokens[p].nullifier ∉ nullifier_set
c ∈ Contents
reviews' = reviews ∪ {review record}
nullifier_set' = nullifier_set ∪ {nullifier}
tokens'[p].status = SPENT
tokens[p].status = ISSUED
No review exists for this token
(Refund scenario)
tokens'[p].status = REVOKED
Token can never be submitted
The Next relation is the disjunction of all actions. At every state,
TLC fires every enabled action, exploring all possible interleavings.
The EV-008 harness uses MaxView=0, meaning view-change transitions
are not exercised. In the full v1.9 spec, AdvanceView and
AdvanceHeight actions exist but are not in the critical path for
the current safety proof. Extending to MaxView ≥ 1 to verify view-change lock
propagation is the next verification milestone.
The project-file Consensus.tla (84 lines) was the starting point.
REFConsensus_v1.9.tla is the verified artifact. Key differences:
EV-008 artifact path: verification/evidence/EV-008_v1.9_final/
containing REFConsensus_v1.9.tla, REFConsensus_v1.9_bft_tiny.cfg,
tlc_bft_tiny_COMPLETE.log, VERIFICATION_NOTES.md, and SHA256SUMS.txt.
EV-009 artifact path: token-lifecycle/ containing
TokenLifecycle.tla, TokenLifecycle.cfg, and
tlc_token_lifecycle.log.