Hi all,
I am a PhD student in the Convecs team at INRIA (France), which works on formal
methods. I am currently modeling Raft in LNT (a formal specification
language developed by Convecs) in order to use the CADP [1] toolbox for
verifications.
While reading through the Raft paper [2] and the TLA+ specification [3], it
seems to me that the specification misses a small state change. I am not fluent
in TLA+ though, so I may have just misunderstood the specification.
Liked depicted in Figure 4 in the paper, if a candidate discover a current
leader, it must become a follower. However, according to the formal
specification, it seems to me that a candidate which discover a leader with the
same term will not change state to become a follower.
Let's illustrate with a small example:
- SC is candidate for term t
- SL was also candidate for the same term, and has become leader for term t
- SL sends a heartbeat with term t to SC
- SC receives the heartbeat (i.e. a append entries request with 0
entry) with term t
At that point, according to the TLA+ specification, in Receive:
- UpdateTerm is not "evaluated", since m.mterm == currentTerm[SC]
- SC evaluates HandleAppendEntriesRequest:
- it will accept the heartbeat
- however, the state variable is not changed anywhere inside
HandleAppendEntriesRequest, so SC continue to be in state candidate
It seems to me that HandleAppendEntriesRequest should set the state of i to
follower as soon as m.mterm == currentTerm. I looked at the implementation of
LogCabin [4] and goraft [5], and candidates do "step down" to follower when a
new leader is elected.
I don't think this impacts the protocol correctness, since a non-elected
candidate behaves almost like a follower, the main difference being a candidate
never grant its vote to another one (and in the example the leader for this term
is already elected anyway). It could even be on purpose that the state is not
changed, as less variable modifications may simplify the formal specification.
What do you think about it ?
[1]
http://cadp.inria.fr
[2]
http://ramcloud.stanford.edu/raft.pdf
[3]
https://ramcloud.stanford.edu/~ongaro/raft.tla
[4]
https://github.com/logcabin/logcabin
[5]
https://github.com/goraft/raft
Thanks,
--
Hugues Evrard
Inria & LIG - Team CONVECS -
http://convecs.inria.fr - @convecs