Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ Here is a list of specs included in this repository which are validated by the C
| [DAG-based Consensus](specifications/dag-consensus) | Giuliano Losa | | | ✔ | ✔ | |
| [German Cache-Coherence Protocol](specifications/GermanProtocol) | Markus Kuppe | | | | ✔ | ✔ |
| [FLASH Cache-Coherence Protocol](specifications/FlashProtocol) | Markus Kuppe | | | | ✔ | ✔ |
| [Vortex DSE](specifications/VortexDSE) | Vasilis Nasopoulos | | ✔ | | ✔ | |


## Other Examples
Expand Down
17 changes: 17 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
\* Safety model. The horizon is imposed inside MCTick; see the module
\* header for why a state constraint does not work here.

SPECIFICATION MCSpec

CONSTANTS
Nodes = {n1, n2}
MsgIDs = {m1, m2}
MaxSlot = 2

INVARIANT MCTypeInvariant
INVARIANT NoFutureAdmission
INVARIANT ExactlyOncePerNode
INVARIANT NoPhantomProcess
INVARIANT DecisionLocalityOnly


73 changes: 73 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot.tla
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---- MODULE MC_Vortex_DSE_CSlot ----
(***************************************************************************)
(* TLC harness for Vortex_DSE_CSlot. *)
(* *)
(* The specification has no slot horizon: Tick is unbounded and the *)
(* adversary may forge any slot in Nat. The horizon is a model-checking *)
(* concern and lives here. *)
(* *)
(* It is imposed inside MCTick rather than as a state CONSTRAINT. A *)
(* constraint was tried first, as the review guidelines prefer, but TLC *)
(* evaluates invariants on the state that crosses the boundary before the *)
(* constraint discards it: with MaxSlot = 2 a Tick produces current_slot = *)
(* 3, and any invariant mentioning the horizon fails there. Bounding the *)
(* ticker instead keeps the reachable graph inside the horizon. *)
(* *)
(* It also avoids a second problem in the liveness model, where discarding *)
(* successor states can mask or invent violations of temporal properties. *)
(* *)
(* MCNext restricts the forged slot as well, because TLC cannot enumerate *)
(* Nat. *)
(***************************************************************************)
EXTENDS Vortex_DSE_CSlot

CONSTANT MaxSlot

ASSUME MaxSlotAssumption == MaxSlot \in Nat

Slots == 0..MaxSlot

MCMsgRecord == [id: MsgIDs, cslot: Slots]

\* The ticker stops at the horizon.
MCTick ==
/\ current_slot < MaxSlot
/\ Tick

MCNext ==
\/ \E id \in MsgIDs, k \in Slots : Send(id, k)
\/ \E n \in Nodes, m \in network : Process(n, m)
\/ \E n \in Nodes : Crash(n)
\/ \E n \in Nodes : Rejoin(n)
\/ MCTick

MCSpec == Init /\ [][MCNext]_vars

\* Type correctness within the horizon. TLC cannot evaluate the
\* specification's own TypeInvariant, whose MsgRecord ranges over Nat.
MCTypeInvariant ==
/\ current_slot \in Slots
/\ network \subseteq MCMsgRecord
/\ processed \in [Nodes -> SUBSET MsgIDs]
/\ persisted \in [Nodes -> SUBSET MsgIDs]
/\ node_state \in [Nodes -> {Up, Down}]

-------------------------------------------------------------------------------
(* LIVENESS HARNESS *)

\* Strong fairness on Process is necessary, not decorative: with weak
\* fairness the liveness model reports a temporal-property violation,
\* because a crash intermittently disables Process.
MCFairness ==
/\ WF_vars(MCTick)
/\ \A n \in Nodes : WF_vars(Rejoin(n))
/\ \A n \in Nodes : SF_vars(\E m \in network : Process(n, m))

MCLiveSpec == Init /\ [][MCNext]_vars /\ MCFairness

\* Bounded counterpart of TickProgress, strengthened as suggested: once the
\* ticker reaches the horizon MCTick is permanently disabled, so the slot
\* counter stays there rather than merely visiting it.
MCTickProgress == <>[](current_slot = MaxSlot)

====
51 changes: 51 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_AE.tla
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---------------- MODULE MC_Vortex_DSE_CSlot_AE ----------------
(***************************************************************************)
(* Harness for Vortex_DSE_CSlot_AE, used by both TLC and Apalache. *)
(* *)
(* The specification has no slot horizon; NextCslot advances without bound *)
(* and DuplicateInject may forge any slot in Nat. The horizon is a *)
(* model-checking concern and is imposed here inside the actions, not as a *)
(* CONSTRAINT, so no successor state is discarded while temporal properties *)
(* are checked. *)
(* *)
(* Invariants are deliberately left separate rather than bundled into one *)
(* conjunction, so that a checker reports which one was violated. *)
(***************************************************************************)
EXTENDS Vortex_DSE_CSlot_AE

CONSTANT MaxSlot

Slots == 0..MaxSlot

MCNextCslot ==
/\ current_slot < MaxSlot
/\ NextCslot

MCNext ==
\/ \E id \in MsgIDs, k \in Slots : Send(id, k)
\/ \E n \in Nodes, m \in network : Process(n, m)
\/ \E n \in Nodes : Freeze(n)
\/ Reconcile
\/ MCNextCslot

MCSpec == Init /\ [][MCNext]_vars

MCFairness ==
/\ WF_vars(Reconcile)
/\ WF_vars(MCNextCslot)
/\ \A n \in Nodes : WF_vars(Freeze(n))

MCLiveSpec == Init /\ [][MCNext]_vars /\ MCFairness

MCTypeInvariant ==
/\ TypeInvariant
/\ current_slot \in Slots
/\ \A m \in network : m.cslot \in Slots

\* Apalache entry point: constants fixed symbolically.
ConstInit ==
/\ Nodes = {"n1", "n2"}
/\ MsgIDs = {"a", "b"}
/\ MaxSlot = 1

===============================================================
12 changes: 12 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_AE_liveness.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
\* Liveness model. Bounded through MCNext rather than a CONSTRAINT.

SPECIFICATION MCLiveSpec

CONSTANTS
Nodes = {n1, n2}
MsgIDs = {m1}
MaxSlot = 1

PROPERTIES

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Careful when checking liveness properties under state- and action-constraints.

EventualCommit
EventualAgreement
18 changes: 18 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_AE_tiny.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
\* Safety model for the agreement layer, under adversarial replay.

SPECIFICATION MCSpec

CONSTANTS
Nodes = {n1, n2}
MsgIDs = {m1, m2}
MaxSlot = 2

INVARIANTS
MCTypeInvariant
ProcessedAreCurrentSlot
CommittedIsUnion
MerkleAgreement
CommittedSupersetsProcessed
NoPhantomInCommitted
NoReorderAcrossCslot
PhaseProgressionValid
17 changes: 17 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_Skew.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
\* Per-node clocks under bounded skew, with Byzantine slot/origin spoofing.

SPECIFICATION MCSpec

CONSTANTS
Nodes = {n1, n2}
MsgIDs = {m1}
MaxSkew = 1
MaxSlot = 2

INVARIANTS
MCTypeInvariant
BoundedSkew
ExactlyOncePerNode
CSlotLocalAdmission
PersistedReflectsReality
NoPhantomProcess
34 changes: 34 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_Skew.tla
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
---- MODULE MC_Vortex_DSE_CSlot_Skew ----
(***************************************************************************)
(* TLC harness for Vortex_DSE_CSlot_Skew. *)
(* *)
(* MaxSkew is a protocol parameter and stays in the specification: it is *)
(* the assumption the protocol relies on. MaxSlot is only a horizon for *)
(* model checking, so it lives here and bounds the actions directly. *)
(***************************************************************************)
EXTENDS Vortex_DSE_CSlot_Skew

CONSTANT MaxSlot

Slots == 0..MaxSlot

MCTick(n) ==
/\ node_slot[n] < MaxSlot
/\ SkewedTick(n)

MCNext ==
\/ \E id \in MsgIDs, n \in Nodes : Submit(id, n)
\/ \E n \in Nodes, m \in network : Process(n, m)
\/ \E n \in Nodes : Crash(n)
\/ \E n \in Nodes : Rejoin(n)
\/ \E id \in MsgIDs, k \in Slots : ByzantineInject(id, k)
\/ \E n \in Nodes : MCTick(n)

MCSpec == Init /\ [][MCNext]_vars

MCTypeInvariant ==
/\ TypeInvariant
/\ node_slot \in [Nodes -> Slots]
/\ \A m \in network : m.cslot \in Slots

====
17 changes: 17 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_TTL.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
\* Safety model for the strict (opt-in TTL) admission mode.

SPECIFICATION MCSpec

CONSTANTS
Nodes = {n1, n2}
MsgIDs = {m1, m2}
MaxSlot = 4

INVARIANTS
MCTypeInvariant
ExactlyOncePerNode
CSlotStrictAdmission
PersistedReflectsReality
NoPhantomProcess
DecisionLocalityOnly
NoLateAdmission
41 changes: 41 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_TTL.tla
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
---- MODULE MC_Vortex_DSE_CSlot_TTL ----
(***************************************************************************)
(* TLC harness for Vortex_DSE_CSlot_TTL. *)
(* *)
(* As in MC_Vortex_DSE_CSlot, the slot horizon is a model-checking concern *)
(* and is imposed inside the actions rather than as a CONSTRAINT, so that *)
(* no successor state is discarded while temporal properties are checked. *)
(***************************************************************************)
EXTENDS Vortex_DSE_CSlot_TTL

CONSTANT MaxSlot

Slots == 0..MaxSlot

MCTick ==
/\ current_slot < MaxSlot
/\ Tick

MCNext ==
\/ \E id \in MsgIDs, k \in Slots : Send(id, k)
\/ \E n \in Nodes, m \in network : Process(n, m)
\/ \E n \in Nodes : Crash(n)
\/ \E n \in Nodes : Rejoin(n)
\/ MCTick

MCSpec == Init /\ [][MCNext]_vars

MCFairness ==
/\ WF_vars(MCTick)
/\ \A n \in Nodes : WF_vars(Rejoin(n))

MCLiveSpec == Init /\ [][MCNext]_vars /\ MCFairness

MCTickProgress == <>[](current_slot = MaxSlot)

MCTypeInvariant ==
/\ TypeInvariant
/\ current_slot \in Slots
/\ \A m \in network : m.cslot \in Slots

====
13 changes: 13 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_TTL_admission.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
\* A deliberate liveness failure. Under the strict gate a message whose slot
\* has passed is refused for good, so eventual admission does not hold. This
\* is what the bounded-memory mode costs, and it is the reason the strict
\* rule is a concession rather than a stronger protocol.

SPECIFICATION MCLiveSpec

CONSTANTS
Nodes = {n1, n2}
MsgIDs = {m1}
MaxSlot = 1

PROPERTY EventualAdmission
12 changes: 12 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_TTL_liveness.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
\* Liveness model. Bounded through MCNext rather than a CONSTRAINT.

SPECIFICATION MCLiveSpec

CONSTANTS
Nodes = {n1, n2}
MsgIDs = {m1}
MaxSlot = 2

PROPERTIES
MCTickProgress
EventualRejoin
14 changes: 14 additions & 0 deletions specifications/VortexDSE/MC_Vortex_DSE_CSlot_liveness.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
\* Liveness model. Bounded inside MCTick rather than by a state constraint,
\* so no successor state is discarded while temporal properties are checked.

SPECIFICATION MCLiveSpec

CONSTANTS
Nodes = {n1, n2}
MsgIDs = {m1}
MaxSlot = 1

PROPERTIES
MCTickProgress
EventualRejoin
EventualAdmission
Loading
Loading