Skip to content
Draft
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ build
.rocks
build.luarocks
.DS_Store

# TLA+ files
states/
*_TTrace_*
822 changes: 822 additions & 0 deletions proofs/tla/src/storage.tla

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions proofs/tla/src/utils.tla
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
------------------------------- MODULE utils -----------------------------------

EXTENDS Naturals, FiniteSets

RECURSIVE SetSum(_)
SetSum(set) == IF set = {} THEN 0 ELSE
LET x == CHOOSE x \in set: TRUE
IN x + SetSum(set \ {x})

================================================================================
27 changes: 27 additions & 0 deletions proofs/tla/test/storage/DoubledBigTest.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
INIT Init
NEXT Next

CONSTANTS
Storages <- StoragesC
ReplicaSets <- ReplicaSetsC
BucketIds <- BucketIdsC
StorageAssignments <- StorageAssignmentsC
BucketAssignments <- BucketAssignmentsC
MasterAssignments <- MasterAssignmentsC
b1 = b1
b2 = b2
b3 = b3
b4 = b4

SYMMETRY Symmetry

INVARIANTS
NetworkTypeInv
StorageTypeInv
StorageToReplicasetTypeInv
NoActiveSimultaneousInv

CONSTRAINT
SendLimitConstraint
NetworkBoundConstraint
RefConstraint
70 changes: 70 additions & 0 deletions proofs/tla/test/storage/DoubledBigTest.tla
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
--------------------------- MODULE DoubledBigTest ------------------------------
EXTENDS storage, utils

CONSTANTS b1, b2, b3, b4

StoragesC == {"s1", "s2", "s3", "s4"}
ReplicaSetsC == {"rs1", "rs2", "rs3"}
BucketIdsC == {b1, b2, b3, b4}
StorageAssignmentsC == [rs1 |-> {"s1", "s2"},
rs2 |-> {"s3"},
rs3 |-> {"s4"}]
BucketAssignmentsC == [rs1 |-> {b1},
rs2 |-> {b2},
rs3 |-> {b3, b4}]
MasterAssignmentsC == [rs1 |-> {"s1"},
rs2 |-> {"s3"},
rs3 |-> {"s4"}]

(***************************************************************************)
(* CONSTRAINTS *)
(***************************************************************************)

MAX_TOTAL_SENDS == 3

\* 1. Limit total bucket sends - prevent endless transfers.
SendLimitConstraint ==
LET totalSends ==
SetSum({ storages[i].errinj.bucketSendCount : i \in StoragesC })
IN totalSends =< MAX_TOTAL_SENDS

\* 2. Keep network bounded - avoid message explosion.
NetworkBoundConstraint ==
/\ \A s1, s2 \in StoragesC :
Len(network[s1][s2]) =< 3
/\ \A s \in StoragesC :
/\ storages[s].errinj.networkReorderCount <= 2
/\ storages[s].errinj.networkDropCount <= 2

RefConstraint ==
\A s1 \in StoragesC :
/\ storages[s1].errinj.bucketRWRefCount <= 2
/\ storages[s1].errinj.bucketRORefCount <= 2
/\ storages[s1].errinj.bucketRWUnRefCount <= 2
/\ storages[s1].errinj.bucketROUnRefCount <= 2

(***************************************************************************)
(* SYMMETRY *)
(***************************************************************************)

Symmetry ==
Permutations(BucketIdsC)

(***************************************************************************)
(* STATE INVARIANTS *)
(***************************************************************************)

NoActiveSimultaneousInv ==
\* No bucket can be ACTIVE in storages belonging to different ReplicaSets
\A b \in BucketIds :
\A rs1, rs2 \in ReplicaSets :
rs1 # rs2 =>
~(\E s1, s2 \in Storages :
storageToReplicaset[s1] = rs1 /\
storageToReplicaset[s2] = rs2 /\
storages[s1].status = "master" /\
storages[s2].status = "master" /\
storages[s1].buckets[b].status = "ACTIVE" /\
storages[s2].buckets[b].status = "ACTIVE")

================================================================================
25 changes: 25 additions & 0 deletions proofs/tla/test/storage/DoubledBucketsSmallTest.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
INIT Init
NEXT Next

CONSTANTS
Storages <- StoragesC
ReplicaSets <- ReplicaSetsC
BucketIds <- BucketIdsC
StorageAssignments <- StorageAssignmentsC
BucketAssignments <- BucketAssignmentsC
MasterAssignments <- MasterAssignmentsC
b1 = b1
b2 = b2

SYMMETRY Symmetry

INVARIANTS
NetworkTypeInv
StorageTypeInv
StorageToReplicasetTypeInv
NoActiveSimultaneousInv

CONSTRAINTS
SendLimitConstraint
NetworkBoundConstraint
TwoMastersConstraint
61 changes: 61 additions & 0 deletions proofs/tla/test/storage/DoubledBucketsSmallTest.tla
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
-------------------------MODULE DoubledBucketsSmallTest ------------------------
EXTENDS storage, utils

CONSTANTS b1, b2

StoragesC == {"s1", "s2", "s3", "s4"}
ReplicaSetsC == {"rs1", "rs2"}
BucketIdsC == {b1, b2}
StorageAssignmentsC == [rs1 |-> {"s1", "s2"},
rs2 |-> {"s3", "s4"}]
BucketAssignmentsC == [rs1 |-> {b1},
rs2 |-> {b2}]
MasterAssignmentsC == [rs1 |-> {"s1"},
rs2 |-> {"s3"}]

(***************************************************************************)
(* CONSTRAINTS *)
(***************************************************************************)

MAX_TOTAL_SENDS == 1

\* 1. Limit total bucket sends - prevent endless transfers.
SendLimitConstraint ==
LET totalSends ==
SetSum({ storages[i].errinj.bucketSendCount : i \in Storages })
IN totalSends =< MAX_TOTAL_SENDS

\* 2. Allow only a small number of concurrent masters.
TwoMastersConstraint ==
Cardinality({s \in Storages : storages[s].status = "master"}) =< 2

\* 3. Keep network bounded - avoid message explosion.
NetworkBoundConstraint ==
\A s1, s2 \in StoragesC :
Len(network[s1][s2]) =< 2

(***************************************************************************)
(* SYMMETRY *)
(***************************************************************************)

Symmetry ==
Permutations(BucketIdsC)

(***************************************************************************)
(* STATE INVARIANTS *)
(***************************************************************************)

NoActiveSimultaneousInv ==
\* No bucket can be ACTIVE in storages belonging to different ReplicaSets
\A b \in BucketIds :
\A rs1, rs2 \in ReplicaSets :
rs1 # rs2 =>
~(\E s1, s2 \in Storages :
storageToReplicaset[s1] = rs1 /\
storageToReplicaset[s2] = rs2 /\
storages[s1].status = "master" /\
storages[s2].status = "master" /\
storages[s1].buckets[b].status = "ACTIVE" /\
storages[s2].buckets[b].status = "ACTIVE")

================================================================================
26 changes: 26 additions & 0 deletions proofs/tla/test/storage/DoubledBucketsTest.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
INIT Init
NEXT Next

CONSTANTS
Storages <- StoragesC
ReplicaSets <- ReplicaSetsC
BucketIds <- BucketIdsC
StorageAssignments <- StorageAssignmentsC
BucketAssignments <- BucketAssignmentsC
MasterAssignments <- MasterAssignmentsC
b1 = b1
b2 = b2
b3 = b3

SYMMETRY Symmetry

INVARIANTS
NetworkTypeInv
StorageTypeInv
StorageToReplicasetTypeInv
NoActiveSimultaneousInv

CONSTRAINT
SendLimitConstraint
NetworkBoundConstraint
RefConstraint
74 changes: 74 additions & 0 deletions proofs/tla/test/storage/DoubledBucketsTest.tla
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
------------------------- MODULE DoubledBucketsTest ----------------------------
EXTENDS storage, utils

CONSTANTS b1, b2, b3

StoragesC == {"s1", "s2", "s3"}
ReplicaSetsC == {"rs1", "rs2", "rs3"}
BucketIdsC == {b1, b2, b3}
StorageAssignmentsC == [rs1 |-> {"s1"},
rs2 |-> {"s2"},
rs3 |-> {"s3"}]
BucketAssignmentsC == [rs1 |-> {b1},
rs2 |-> {b2},
rs3 |-> {b3}]
MasterAssignmentsC == [rs1 |-> {"s1"},
rs2 |-> {"s2"},
rs3 |-> {"s3"}]

(***************************************************************************)
(* CONSTRAINTS *)
(***************************************************************************)

MAX_TOTAL_SENDS == 2

\* 1. Limit total bucket sends - prevent endless transfers.
SendLimitConstraint ==
LET totalSends ==
SetSum({ storages[i].errinj.bucketSendCount : i \in StoragesC })
IN totalSends =< MAX_TOTAL_SENDS

\* 2. Keep network bounded - avoid message explosion.
NetworkBoundConstraint ==
/\ \A s1, s2 \in StoragesC :
Len(network[s1][s2]) =< 2
/\ \A s \in StoragesC :
/\ storages[s].errinj.networkReorderCount <= 2
/\ storages[s].errinj.networkDropCount <= 2

RefConstraint ==
\A s1 \in StoragesC :
/\ storages[s1].errinj.bucketRWRefCount <= 0
/\ storages[s1].errinj.bucketRORefCount <= 0
/\ storages[s1].errinj.bucketRWUnRefCount <= 0
/\ storages[s1].errinj.bucketROUnRefCount <= 0

(***************************************************************************)
(* SYMMETRY *)
(***************************************************************************)

Symmetry ==
Permutations(BucketIdsC)

(***************************************************************************)
(* STATE INVARIANTS *)
(***************************************************************************)

NoActiveSimultaneousInv ==
\* No bucket can be ACTIVE in storages belonging to different ReplicaSets
\A b \in BucketIds :
\A rs1, rs2 \in ReplicaSets :
rs1 # rs2 =>
~(\E s1, s2 \in Storages :
storageToReplicaset[s1] = rs1 /\
storageToReplicaset[s2] = rs2 /\
storages[s1].status = "master" /\
storages[s2].status = "master" /\
storages[s1].buckets[b].status = "ACTIVE" /\
storages[s2].buckets[b].status = "ACTIVE")

(***************************************************************************)
(* MODEL CHECKING PROPERTIES *)
(***************************************************************************)

================================================================================
20 changes: 20 additions & 0 deletions proofs/tla/test/storage/MasterDoubledTest.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
INIT TestInit
NEXT TestNext

CONSTANTS
Storages <- StoragesC
ReplicaSets <- ReplicaSetsC
BucketIds <- BucketIdsC
StorageAssignments <- StorageAssignmentsC
BucketAssignments <- BucketAssignmentsC
MasterAssignments <- MasterAssignmentsC
b1 = b1
b2 = b2
b3 = b3
b4 = b4

INVARIANTS
NetworkTypeInv
StorageTypeInv
StorageToReplicasetTypeInv
NoActiveSimultaneousInv
Loading
Loading