Update `LogInv` in the TLA+ spec (#5206)

This commit is contained in:
Heidi Howard 2023-04-26 11:05:47 +01:00 коммит произвёл GitHub
Родитель 97a6cd7425
Коммит 08035fac0e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
4 изменённых файлов: 31 добавлений и 33 удалений

Просмотреть файл

@ -41,9 +41,8 @@ CHECK_DEADLOCK
FALSE
PROPERTIES
CommittedLogAppendOnlyProp
MonotonicTermProp
MonotonicCommitIndexProp
CommittedLogNeverChangesProp
PermittedLogChangesProp
StateTransitionsProp
PendingBecomesFollowerProp

Просмотреть файл

@ -34,9 +34,8 @@ CHECK_DEADLOCK
TRUE
PROPERTIES
CommittedLogAppendOnlyProp
MonotonicTermProp
MonotonicCommitIndexProp
CommittedLogNeverChangesProp
PermittedLogChangesProp
StateTransitionsProp
PendingBecomesFollowerProp

Просмотреть файл

@ -407,7 +407,6 @@ TraceAlias ==
log |-> log,
commitIndex |-> commitIndex,
clientRequests |-> clientRequests,
committedLog |-> committedLog,
votesGranted |-> votesGranted,
votesRequested |-> votesRequested,
nextIndex |-> nextIndex,

Просмотреть файл

@ -15,7 +15,7 @@
\* - https://github.com/ongardie/raft.tla/blob/master/raft.tla
\* (base spec, modified)
\* - https://github.com/jinlmsft/raft.tla/blob/master/raft.tla
\* (e.g. clientRequests, committedLog)
\* (e.g. clientRequests)
\* - https://github.com/dricketts/raft.tla/blob/master/raft.tla
\* (e.g. certain invariants)
@ -280,22 +280,12 @@ VARIABLE clientRequests
ClientRequestsTypeInv ==
clientRequests \in Nat \ {0}
\* The log and index denoting the operations that have been committed. Instead
\* of copying the committed prefix of the current leader's log, remember the
\* node and the index (up to which the operations have been committed) into its log.
\* This variable is a history variable in TLA+ jargon. It does not exist in an implementation.
VARIABLE committedLog
CommittedLogTypeInv ==
committedLog \in [ node: Servers, index: Nat ]
logVars == <<log, commitIndex, clientRequests, committedLog>>
logVars == <<log, commitIndex, clientRequests>>
LogVarsTypeInv ==
/\ LogTypeInv
/\ CommitIndexTypeInv
/\ ClientRequestsTypeInv
/\ CommittedLogTypeInv
\* The set of servers from which the candidate has received a vote in its
\* currentTerm.
@ -567,7 +557,6 @@ InitLogVars ==
/\ log = [i \in Servers |-> << >>]
/\ commitIndex = [i \in Servers |-> 0]
/\ clientRequests = 1
/\ committedLog = [ node |-> NodeOne, index |-> 0]
Init ==
/\ InitReconfigurationVars
@ -677,7 +666,7 @@ BecomeLeader(i) ==
\* Shorten the configurations if the removed txs contained reconfigurations
/\ configurations' = [configurations EXCEPT ![i] = ConfigurationsToIndex(i, new_max_index)]
/\ UNCHANGED <<reconfigurationCount, removedFromConfiguration, messageVars, currentTerm, votedFor,
votesRequested, candidateVars, commitIndex, clientRequests, committedLog>>
votesRequested, candidateVars, commitIndex, clientRequests>>
\* Leader i receives a client request to add v to the log.
ClientRequest(i) ==
@ -694,7 +683,7 @@ ClientRequest(i) ==
\* Make sure that each request is unique, reduce state space to be explored
/\ clientRequests' = clientRequests + 1
/\ UNCHANGED <<reconfigurationVars, messageVars, serverVars, candidateVars,
leaderVars, commitIndex, committedLog>>
leaderVars, commitIndex>>
\* CCF: Signed commits
\* In CCF, the leader periodically signs the latest log prefix. Only these signatures are committable in CCF.
@ -720,7 +709,7 @@ SignCommittableMessages(i) ==
newLog == Append(log[i], entry)
IN log' = [log EXCEPT ![i] = newLog]
/\ UNCHANGED <<reconfigurationVars, messageVars, serverVars, candidateVars, clientRequests,
leaderVars, commitIndex, committedLog>>
leaderVars, commitIndex>>
\* CCF: Reconfiguration of servers
\* In the TLA+ model, a reconfiguration is initiated by the Leader which appends an arbitrary new configuration to its own log.
@ -755,7 +744,7 @@ ChangeConfigurationInt(i, newConfiguration) ==
/\ log' = [log EXCEPT ![i] = newLog]
/\ configurations' = [configurations EXCEPT ![i] = @ @@ Len(log[i]) + 1 :> newConfiguration]
/\ UNCHANGED <<messageVars, serverVars, candidateVars, clientRequests,
leaderVars, commitIndex, committedLog>>
leaderVars, commitIndex>>
ChangeConfiguration(i) ==
\E newConfiguration \in SUBSET(Servers \ removedFromConfiguration) :
@ -796,7 +785,6 @@ AdvanceCommitIndex(i) ==
\* only advance if necessary (this is basically a sanity check after the Min above)
/\ commitIndex[i] < new_index
/\ commitIndex' = [commitIndex EXCEPT ![i] = new_index]
/\ committedLog' = IF new_index > committedLog.index THEN [ node |-> i, index |-> new_index ] ELSE committedLog
\* If commit index surpasses the next configuration, pop configs, and retire as leader if removed
/\ IF /\ Cardinality(DOMAIN configurations[i]) > 1
/\ new_index >= NextConfigurationIndex(i)
@ -921,7 +909,7 @@ AppendEntriesAlreadyDone(i, j, index, m) ==
source |-> i,
dest |-> j],
m)
/\ UNCHANGED <<reconfigurationCount, removedFromConfiguration, messagesSent, commitsNotified, serverVars, log, clientRequests, committedLog>>
/\ UNCHANGED <<reconfigurationCount, removedFromConfiguration, messagesSent, commitsNotified, serverVars, log, clientRequests>>
ConflictAppendEntriesRequest(i, index, m) ==
/\ m.entries /= << >>
@ -937,7 +925,7 @@ ConflictAppendEntriesRequest(i, index, m) ==
|-> [n \in 1..min(Len(messagesSent[i][j]) - 1, index - 1)
|-> messagesSent[i][j][n]]]
IN messagesSent' = [messagesSent EXCEPT ![i] = newCounts ]
/\ UNCHANGED <<reconfigurationCount, removedFromConfiguration, serverVars, commitIndex, messages, commitsNotified, clientRequests, committedLog>>
/\ UNCHANGED <<reconfigurationCount, removedFromConfiguration, serverVars, commitIndex, messages, commitsNotified, clientRequests>>
NoConflictAppendEntriesRequest(i, j, m) ==
/\ m.entries /= << >>
@ -975,7 +963,7 @@ NoConflictAppendEntriesRequest(i, j, m) ==
source |-> i,
dest |-> j],
m)
/\ UNCHANGED <<reconfigurationCount, removedFromConfiguration, messagesSent, commitsNotified, currentTerm, votedFor, clientRequests, committedLog>>
/\ UNCHANGED <<reconfigurationCount, removedFromConfiguration, messagesSent, commitsNotified, currentTerm, votedFor, clientRequests>>
AcceptAppendEntriesRequest(i, j, logOk, m) ==
\* accept request
@ -1057,7 +1045,7 @@ UpdateCommitIndex(i,j,m) ==
/\ commitIndex' = [commitIndex EXCEPT ![i] = m.commitIndex]
/\ configurations' = [configurations EXCEPT ![i] = new_configurations]
/\ UNCHANGED <<reconfigurationCount, messages, messagesSent, commitsNotified, currentTerm,
votedFor, candidateVars, leaderVars, log, clientRequests, committedLog>>
votedFor, candidateVars, leaderVars, log, clientRequests>>
\* Receive a message.
Messages ==
@ -1141,9 +1129,15 @@ Spec == Init /\ [][Next]_vars
\* Correctness invariants
\* These invariants should be true for all possible states
\* Committed log entries should not conflict
\* Committed log entries should never conflict between servers
LogInv ==
/\ \A i \in Servers : IsPrefix(Committed(i),SubSeq(log[committedLog.node],1,committedLog.index))
\A i, j \in Servers :
\/ IsPrefix(Committed(i),Committed(j))
\/ IsPrefix(Committed(j),Committed(i))
\* Note that LogInv checks for safety violations across space
\* This is a key safety invariant and should always be checked
THEOREM Spec => []LogInv
\* There should not be more than one leader per term at the same time
\* Note that this does not rule out multiple leaders in the same term at different times
@ -1276,17 +1270,24 @@ NoLeaderInTermZeroInv ==
------------------------------------------------------------------------------
\* Properties
MonotonicTermProp ==
\* Each server's committed log is append-only
CommittedLogAppendOnlyProp ==
[][\A i \in Servers :
currentTerm[i]' >= currentTerm[i]]_vars
IsPrefix(Committed(i), Committed(i)')]_vars
\* Note that CommittedLogAppendOnlyProp checks for safety violations across time
\* This is a key safety invariant and should always be checked
THEOREM Spec => CommittedLogAppendOnlyProp
\* Each server's commit index is monotonically increasing
\* This is weaker form of CommittedLogAppendOnlyProp so it is not checked by default
MonotonicCommitIndexProp ==
[][\A i \in Servers :
commitIndex[i]' >= commitIndex[i]]_vars
CommittedLogNeverChangesProp ==
MonotonicTermProp ==
[][\A i \in Servers :
IsPrefix(Committed(i), Committed(i)')]_vars
currentTerm[i]' >= currentTerm[i]]_vars
PermittedLogChangesProp ==
[][\A i \in Servers :