@@ -54,40 +54,35 @@ TraceServer == TLCEval(FoldSeq(
5454 THEN { x . event . nid , x . event . prop . cc . changes [ 1 ] . nid }
5555 ELSE { x . event . nid } ,
5656 { } , TraceLog ) )
57-
58- BootstrapLogIndicesForServer ( i ) ==
59- LET
60- FirstBootstrapLogIndex == SelectInSeq ( TraceLog , LAMBDA x : x . event . nid = i /\ x . event . name \in { "InitState" , "BecomeFollower" , "ApplyConfChange" } )
61- FirstNonBootstrapLogIndex == SelectInSeq ( TraceLog , LAMBDA x : x . event . nid = i /\ x . event . name \notin { "InitState" , "BecomeFollower" , "ApplyConfChange" } )
62- LastBootstrapLogIndexUpperBound == IF FirstNonBootstrapLogIndex = 0 THEN Len ( TraceLog ) ELSE FirstNonBootstrapLogIndex - 1
63- IN
64- { k \in FirstBootstrapLogIndex .. LastBootstrapLogIndexUpperBound : TraceLog [ k ] . event . nid = i }
65-
66- BootstrapLogIndices == UNION { BootstrapLogIndicesForServer ( i ) : i \in Server }
67-
68- LastBootstrapLog == [ i \in Server |-> TraceLog [ Max ( BootstrapLogIndicesForServer ( i ) ) ] ]
69-
70- BootstrappedConfig ( i ) ==
71- IF LastBootstrapLog [ i ] . event . name = "ApplyConfChange" THEN
72- ToSet ( LastBootstrapLog [ i ] . event . prop . cc . newconf )
73- ELSE
74- ToSet ( LastBootstrapLog [ i ] . event . conf [ 1 ] )
75-
76- TraceInitServer == BootstrappedConfig ( TraceLog [ 1 ] . event . nid )
57+
58+ BootstrapIndex == [ i \in Server |-> SelectInSeq ( TraceLog , LAMBDA x : x . event . nid = i /\ x . event . name = "Bootstrap" ) ]
59+
60+ TraceInitServer == { i \in Server : BootstrapIndex [ i ] > 0 }
7761ASSUME TraceInitServer \subseteq TraceServer
7862
79- TraceInitServerVars == /\ currentTerm = [ i \in Server |-> LastBootstrapLog [ i ] . event . state . term ]
80- /\ state = [ i \in Server |-> LastBootstrapLog [ i ] . event . role ]
81- /\ votedFor = [ i \in Server |-> LastBootstrapLog [ i ] . event . state . vote ]
82- TraceInitLogVars == /\ log = [ i \in Server |-> [ j \in 1 .. LastBootstrapLog [ i ] . event . log |-> [ term |-> 1 , type |-> "ConfigEntry" , value |-> [ newconf |-> BootstrappedConfig ( i ) , learners |-> { } ] ] ] ]
83- /\ commitIndex = [ i \in Server |-> LastBootstrapLog [ i ] . event . state . commit ]
63+ BootstrapEntries ( i ) == FoldSeq (
64+ LAMBDA x , y : Append ( y , [ term |-> 1 ,
65+ type |-> "ConfigEntry" ,
66+ value |-> [ newconf |-> ToSet ( TraceLog [ x ] . event . prop . cc . newconf ) , learners |-> { } ] ] ) ,
67+ << >> ,
68+ SetToSortSeq ( { j \in DOMAIN TraceLog : /\ j < BootstrapIndex [ i ]
69+ /\ TraceLog [ j ] . event . nid = i
70+ /\ TraceLog [ j ] . event . name = "ApplyConfChange" } , < ) )
71+
72+ TraceInitServerVars == /\ currentTerm = [ i \in Server |-> IF i \in InitServer THEN 1 ELSE 0 ]
73+ /\ state = [ i \in Server |-> Follower ]
74+ /\ votedFor = [ i \in Server |-> Nil ]
75+ TraceInitLogVars == /\ log = [ i \in Server |-> BootstrapEntries ( i ) ]
76+ /\ commitIndex = [ i \in Server |-> Len ( log [ i ] ) ]
77+ /\ applied = [ i \in Server |-> 0 ]
8478TraceInitConfigVars ==
85- /\ config = [ i \in Server |-> [ jointConfig |-> << BootstrappedConfig ( i ) , { } >> , learners |-> { } ] ]
86- /\ reconfigCount = 0
79+ /\ config = [ i \in Server |-> [ jointConfig |-> << IF i \in InitServer THEN ToSet ( TraceLog [ BootstrapIndex [ i ] ] . event . conf [ 1 ] ) ELSE { } , { } >> , learners |-> { } ] ]
80+ /\ appliedConfChange = [ i \in Server |-> Len ( log [ i ] ) ]
8781
8882
8983-------------------------------------------------------------------------------------
90- ConfFromLog ( l ) == << ToSet ( l . event . conf [ 1 ] ) , ToSet ( l . event . conf [ 2 ] ) >>
84+ ConfFromTrace ( l ) == << ToSet ( l . event . conf [ 1 ] ) , ToSet ( l . event . conf [ 2 ] ) >>
85+ NewConfFromTrace ( l ) == << ToSet ( l . event . prop . cc . newconf ) , { } >>
9186
9287OneMoreMessage ( msg ) ==
9388 \/ msg \notin DOMAIN pendingMessages /\ msg \in DOMAIN pendingMessages ' /\ pendingMessages ' [ msg ] = 1
@@ -99,29 +94,44 @@ OneLessMessage(msg) ==
9994
10095-------------------------------------------------------------------------------------
10196
97+ \* In some state, we will restrict the state exploration to only follow the actions in
98+ \* constrained behavior. This is to reduce state space to be explored.
99+ VARIABLE behaviorProgress
100+
101+ Ready_PersistState_SendMessages_Behavior ( i ) ==
102+ << "Ready" , "PersistState" , "SendMessage" >>
103+
104+ StepToNextBehaviorAction ( i ) ==
105+ IF behaviorProgress [ i ] = Len ( Ready_PersistState_SendMessages_Behavior ) THEN
106+ behaviorProgress ' = [ behaviorProgress EXCEPT ! [ i ] = 1 ]
107+ ELSE
108+ behaviorProgress ' = [ behaviorProgress EXCEPT ! [ i ] = @ + 1 ]
109+
110+ IsAllowedBehaviorAction ( i , name ) ==
111+ Ready_PersistState_SendMessages_Behavior [ behaviorProgress [ i ] ] = name
112+
102113VARIABLE l
103114logline == TraceLog [ l ]
104- VARIABLE pl
105-
106115
107116TraceInit ==
108117 /\ l = 1
109- /\ pl = 0
110- /\ logline = TraceLog [ l ]
118+ /\ behaviorProgress = [ i \in Server |-> 1 ]
111119 /\ Init
112120
113121StepToNextTrace ==
114- /\ l ' = l + 1
115- /\ pl ' = l
116- /\ l % ( Len ( TraceLog ) \div 100 ) = 0 => PrintT ( << "Progress %:" , ( l * 100 ) \div Len ( TraceLog ) >> )
117- /\ l ' > Len ( TraceLog ) => PrintT ( << "Progress %:" , 100 >> )
122+ IF behaviorProgress [ logline . event . nid ] > 1 THEN
123+ \* Trace shall stay in current position until all actions
124+ \* in the behavior are performed
125+ UNCHANGED l
126+ ELSE
127+ /\ l ' = l + 1
128+ /\ l % ( Len ( TraceLog ) \div 100 ) = 0 => PrintT ( << "Progress %:" , ( l * 100 ) \div Len ( TraceLog ) >> )
129+ /\ l ' > Len ( TraceLog ) => PrintT ( << "Progress %:" , 100 >> )
118130
119131StepToNextTraceIfMessageIsProcessed ( msg ) ==
120132 IF OneLessMessage ( msg )
121133 THEN StepToNextTrace
122- ELSE
123- /\ pl ' = l
124- /\ UNCHANGED << l >>
134+ ELSE UNCHANGED << l >>
125135
126136-------------------------------------------------------------------------------------
127137
@@ -354,9 +364,19 @@ ApplySimpleConfChangeIfLogged(i) ==
354364 /\ LoglineIsNodeEvent ( "ApplyConfChange" , i )
355365 /\ ApplySimpleConfChange ( i )
356366
357- ReadyIfLogged ( i ) ==
367+ ReadyBehaviorIfLogged ( i ) ==
358368 /\ LoglineIsNodeEvent ( "Ready" , i )
359- /\ Ready ( i )
369+ /\ \/ /\ IsAllowedBehaviorAction ( i , "Ready" )
370+ /\ Ready ( i )
371+ \/ /\ IsAllowedBehaviorAction ( i , "PersistState" )
372+ /\ PersistState ( i )
373+ \/ /\ IsAllowedBehaviorAction ( i , "SendMessages" )
374+ /\ SendMessages ( i )
375+ /\ StepToNextBehaviorAction
376+
377+ AdvanceIfLogged ( i ) ==
378+ /\ LoglineIsNodeEvent ( "Advance" , i )
379+ /\ Advance ( i )
360380
361381RestartIfLogged ( i ) ==
362382 /\ LoglineIsNodeEvent ( "InitState" , i )
@@ -385,7 +405,9 @@ StepDownToFollowerIfLogged(i) ==
385405
386406\* skip unused logs
387407SkipUnusedLogline ==
388- /\ \/ /\ LoglineIsEvent ( "SendAppendEntriesResponse" )
408+ /\ \/ /\ l < Len ( TraceLog )
409+ /\ l <= BootstrapIndex [ logline . event . nid ]
410+ \/ /\ LoglineIsEvent ( "SendAppendEntriesResponse" )
389411 /\ logline . event . msg . from # logline . event . msg . to
390412 \/ /\ LoglineIsEvent ( "SendRequestVoteResponse" )
391413 /\ logline . event . msg . from # logline . event . msg . to
@@ -421,7 +443,9 @@ TraceNextNonReceiveActions ==
421443 \/ /\ LoglineIsEvent ( "ApplyConfChange" )
422444 /\ \E i \in Server : ApplySimpleConfChangeIfLogged ( i )
423445 \/ /\ LoglineIsEvent ( "Ready" )
424- /\ \E i \in Server : ReadyIfLogged ( i )
446+ /\ \E i \in Server : ReadyBehaviorIfLogged ( i )
447+ \/ /\ LoglineIsEvent ( "Advance" )
448+ /\ \E i \in Server : AdvanceIfLogged ( i )
425449 \/ /\ LoglineIsEvent ( "InitState" )
426450 /\ \E i \in Server : RestartIfLogged ( i )
427451 \/ /\ LoglineIsEvent ( "BecomeFollower" )
@@ -444,7 +468,7 @@ TraceNext ==
444468 \/ TraceNextReceiveActions
445469
446470TraceSpec ==
447- TraceInit /\ [] [ TraceNext ]_ << l , pl , vars >>
471+ TraceInit /\ [] [ TraceNext ]_ << l , behaviorProgress , vars >>
448472
449473-------------------------------------------------------------------------------------
450474
@@ -454,7 +478,7 @@ TraceView ==
454478 \* appears the second time in the trace. Put differently, TraceView causes TLC to
455479 \* consider s_i and s_j , where i and j are the positions of s in the trace,
456480 \* to be different states.
457- << vars , l >>
481+ << vars , l , behaviorProgress >>
458482
459483-------------------------------------------------------------------------------------
460484
0 commit comments