Skip to content

Commit ff13c98

Browse files
committed
[draft] Add bootstrap trace to simplify trace validation
1 parent 4d429be commit ff13c98

File tree

4 files changed

+34
-30
lines changed

4 files changed

+34
-30
lines changed

bootstrap.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,5 +76,7 @@ func (rn *RawNode) Bootstrap(peers []Peer) error {
7676
for _, peer := range peers {
7777
rn.raft.applyConfChange(pb.ConfChange{NodeID: peer.ID, Type: pb.ConfChangeAddNode}.AsV2())
7878
}
79+
80+
traceBootstrap(rn.raft)
7981
return nil
8082
}

state_trace.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type stateMachineEventType int
3030

3131
const (
3232
rsmInitState stateMachineEventType = iota
33+
rsmBootstrap
3334
rsmBecomeCandidate
3435
rsmBecomeFollower
3536
rsmBecomeLeader
@@ -53,6 +54,7 @@ const (
5354
func (e stateMachineEventType) String() string {
5455
return []string{
5556
"InitState",
57+
"Bootstrap",
5658
"BecomeCandidate",
5759
"BecomeFollower",
5860
"BecomeLeader",
@@ -206,6 +208,10 @@ func traceInitState(r *raft) {
206208
traceNodeEvent(rsmInitState, r)
207209
}
208210

211+
func traceBootstrap(r *raft) {
212+
traceNodeEvent(rsmBootstrap, r)
213+
}
214+
209215
func traceReady(r *raft) {
210216
traceNodeEvent(rsmReady, r)
211217
}

state_trace_nop.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ type TracingEvent struct{}
2929

3030
func traceInitState(*raft) {}
3131

32+
func traceBootstrap(*raft) {}
33+
3234
func traceReady(*raft) {}
3335

3436
func traceCommit(*raft) {}

tla/Traceetcdraft.tla

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -55,32 +55,24 @@ TraceServer == TLCEval(FoldSeq(
5555
ELSE {x.event.nid},
5656
{}, TraceLog))
5757

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)
58+
BootstrapIndex == [ i \in Server |-> SelectInSeq(TraceLog, LAMBDA x: x.event.nid = i /\ x.event.name = "Bootstrap") ]
59+
BootstrapEntries(i) == FoldSeq(
60+
LAMBDA x, y: Append(y, [ term |-> 1,
61+
type |-> "ConfigEntry",
62+
value |-> [ newconf |-> ToSet(TraceLog[x].event.prop.cc.newconf), learners |-> {}] ]),
63+
<<>>,
64+
SetToSortSeq({j \in DOMAIN TraceLog : /\ j < BootstrapIndex[i]
65+
/\ TraceLog[j].event.nid = i
66+
/\ TraceLog[j].event.name = "ApplyConfChange"}, <) )
67+
68+
TraceInitServer == { i \in Server : BootstrapIndex[i] > 0 }
7769
ASSUME TraceInitServer \subseteq TraceServer
7870

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]
71+
TraceInitServerVars == /\ currentTerm = [i \in Server |-> IF i \in InitServer THEN 1 ELSE 0]
72+
/\ state = [i \in Server |-> Follower]
73+
/\ votedFor = [i \in Server |-> Nil]
74+
TraceInitLogVars == /\ log = [i \in Server |-> BootstrapEntries(i)]
75+
/\ commitIndex = [i \in Server |-> Len(log[i])]
8476
TraceInitConfigVars ==
8577
/\ config = [i \in Server |-> [ jointConfig |-> <<BootstrappedConfig(i), {}>>, learners |-> {}] ]
8678
/\ reconfigCount = 0
@@ -125,6 +117,8 @@ StepToNextTraceIfMessageIsProcessed(msg) ==
125117

126118
-------------------------------------------------------------------------------------
127119

120+
LoglineIsBootStrap == l <= BootstrapIndex[logline.event.nid]
121+
128122
LoglineIsEvent(e) ==
129123
/\ l <= Len(TraceLog)
130124
/\ logline.event.name = e
@@ -436,12 +430,12 @@ TraceNextReceiveActions ==
436430
/\ StepToNextTraceIfMessageIsProcessed(m)
437431

438432
TraceNext ==
439-
\/ /\ l \in BootstrapLogIndices
440-
/\ UNCHANGED <<vars>>
441-
/\ StepToNextTrace
442-
\/ /\ l \notin BootstrapLogIndices
443-
/\ \/ TraceNextNonReceiveActions
444-
\/ TraceNextReceiveActions
433+
IF LoglineIsBootStrap THEN
434+
/\ UNCHANGED <<vars>>
435+
/\ StepToNextTrace
436+
ELSE
437+
\/ TraceNextNonReceiveActions
438+
\/ TraceNextReceiveActions
445439

446440
TraceSpec ==
447441
TraceInit /\ [][TraceNext]_<<l, pl, vars>>

0 commit comments

Comments
 (0)