|
| 1 | +This spec was inspired by https://github.com/microsoft/CCF/blob/main/tla/consensus/abs.tla. |
| 2 | + |
| 3 | +This spec has a machine-closed fairness constraint, which differs from the the CRDT and |
| 4 | +ReplicatedLog examples. However, this spec assumes that a server can consistently read the |
| 5 | +state of all other servers, which is clearly not a realistic assumption for a real |
| 6 | +distributed system. A real system would rely on some messaging protocol to determine the |
| 7 | +lag between servers (compare Raft). |
| 8 | + |
| 9 | +---- MODULE DistributedReplicatedLog ---- |
| 10 | +EXTENDS Sequences, SequencesExt, Integers, FiniteSets, FiniteSetsExt |
| 11 | + |
| 12 | +CONSTANT Lag, Servers, Values |
| 13 | +ASSUME Lag \in Nat /\ IsFiniteSet(Servers) |
| 14 | + |
| 15 | +VARIABLE cLogs |
| 16 | +vars == <<cLogs>> |
| 17 | + |
| 18 | +TypeOK == |
| 19 | + /\ cLogs \in [Servers -> Seq(Values)] |
| 20 | + |
| 21 | +Init == |
| 22 | + /\ cLogs \in [Servers -> {<< >>}] |
| 23 | + |
| 24 | +Copy(i) == |
| 25 | + \E j \in Servers: |
| 26 | + /\ Len(cLogs[j]) > Len(cLogs[i]) |
| 27 | + /\ \* Sync some prefix up to prefix = suffix of the unsynced suffix. |
| 28 | + LET L == (Len(cLogs[j]) - Len(cLogs[i])) |
| 29 | + \* Force to proportionally to the lag L copy more. |
| 30 | + \* Lag: 1 -> 0..L, 2 -> 1..L, 3 -> 2..L |
| 31 | + IN \E l \in L-1 .. L: |
| 32 | + cLogs' = [cLogs EXCEPT ![i] = @ \o SubSeq(cLogs[j], Len(@) + 1, Len(@) + l)] |
| 33 | + |
| 34 | +Extend(i) == |
| 35 | + /\ \A j \in Servers: |
| 36 | + Len(cLogs[j]) \leq Len(cLogs[i]) |
| 37 | + /\ \E s \in BoundedSeq(Values, Lag - Max({Len(cLogs[i]) - Len(cLogs[j]) : j \in Servers})): |
| 38 | + cLogs' = [cLogs EXCEPT ![i] = @ \o s] |
| 39 | + |
| 40 | +Next == |
| 41 | + \E i \in Servers: |
| 42 | + \/ Copy(i) |
| 43 | + \/ Extend(i) |
| 44 | + |
| 45 | +Spec == |
| 46 | + /\ Init |
| 47 | + /\ [][Next]_vars |
| 48 | + /\ \A s \in Servers: WF_vars(Extend(s)) /\ WF_vars(Copy(s)) |
| 49 | + |
| 50 | +---- |
| 51 | +\* Invariants |
| 52 | + |
| 53 | +Abs(n) == |
| 54 | + IF n < 0 THEN -n ELSE n |
| 55 | + |
| 56 | +BoundedLag == |
| 57 | + \A i, j \in Servers: Abs(Len(cLogs[i]) - Len(cLogs[j])) <= Lag |
| 58 | + |
| 59 | +THEOREM Spec => []BoundedLag |
| 60 | + |
| 61 | +---- |
| 62 | +\* Liveness |
| 63 | + |
| 64 | +AllExtending == |
| 65 | + \A s \in Servers: []<><<IsStrictPrefix(cLogs[s], cLogs'[s])>>_cLogs |
| 66 | + |
| 67 | +THEOREM Spec => AllExtending |
| 68 | + |
| 69 | +InSync == |
| 70 | + \* TLC correctly verifies that InSync is not a property of the system because |
| 71 | + \* followers are permitted to copy only a prefix of the missing suffix. |
| 72 | + \A i, j \in Servers : []<>(cLogs[i] = cLogs[j]) |
| 73 | + |
| 74 | +==== |
0 commit comments