forked from tendermint/tendermint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
TendermintAccDebug_004_draft.tla
101 lines (86 loc) · 4 KB
/
TendermintAccDebug_004_draft.tla
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
------------------ MODULE TendermintAccDebug_004_draft -------------------------
(*
A few definitions that we use for debugging TendermintAcc3, which do not belong
to the specification itself.
* Version 3. Modular and parameterized definitions.
Igor Konnov, 2020.
*)
EXTENDS TendermintAccInv_004_draft
\* make them parameters?
NFaultyProposals == 0 \* the number of injected faulty PROPOSE messages
NFaultyPrevotes == 6 \* the number of injected faulty PREVOTE messages
NFaultyPrecommits == 6 \* the number of injected faulty PRECOMMIT messages
\* Given a set of allowed messages Msgs, this operator produces a function from
\* rounds to sets of messages.
\* Importantly, there will be exactly k messages in the image of msgFun.
\* We use this action to produce k faults in an initial state.
\* @type: (ROUND -> Set(MESSAGE), Set(MESSAGE), Int) => Bool;
ProduceFaults(msgFun, From, k) ==
\E f \in [1..k -> From]:
msgFun = [r \in Rounds |-> {m \in {f[i]: i \in 1..k}: m.round = r}]
\* As TLC explodes with faults, we may have initial states without faults
InitNoFaults ==
/\ round = [p \in Corr |-> 0]
/\ step = [p \in Corr |-> "PROPOSE"]
/\ decision = [p \in Corr |-> NilValue]
/\ lockedValue = [p \in Corr |-> NilValue]
/\ lockedRound = [p \in Corr |-> NilRound]
/\ validValue = [p \in Corr |-> NilValue]
/\ validRound = [p \in Corr |-> NilRound]
/\ msgsPropose = [r \in Rounds |-> EmptyMsgSet]
/\ msgsPrevote = [r \in Rounds |-> EmptyMsgSet]
/\ msgsPrecommit = [r \in Rounds |-> EmptyMsgSet]
/\ evidence = EmptyMsgSet
(*
A specialized version of Init that injects NFaultyProposals proposals,
NFaultyPrevotes prevotes, NFaultyPrecommits precommits by the faulty processes
*)
InitFewFaults ==
/\ round = [p \in Corr |-> 0]
/\ step = [p \in Corr |-> "PROPOSE"]
/\ decision = [p \in Corr |-> NilValue]
/\ lockedValue = [p \in Corr |-> NilValue]
/\ lockedRound = [p \in Corr |-> NilRound]
/\ validValue = [p \in Corr |-> NilValue]
/\ validRound = [p \in Corr |-> NilRound]
/\ ProduceFaults(msgsPrevote',
[type: {"PREVOTE"}, src: Faulty, round: Rounds, id: Values],
NFaultyPrevotes)
/\ ProduceFaults(msgsPrecommit',
[type: {"PRECOMMIT"}, src: Faulty, round: Rounds, id: Values],
NFaultyPrecommits)
/\ ProduceFaults(msgsPropose',
[type: {"PROPOSAL"}, src: Faulty, round: Rounds,
proposal: Values, validRound: Rounds \cup {NilRound}],
NFaultyProposals)
/\ evidence = EmptyMsgSet
\* Add faults incrementally
NextWithFaults ==
\* either the protocol makes a step
\/ Next
\* or a faulty process sends a message
\//\ UNCHANGED <<round, step, decision, lockedValue,
lockedRound, validValue, validRound, evidence>>
/\ \E p \in Faulty:
\E r \in Rounds:
\//\ UNCHANGED <<msgsPrevote, msgsPrecommit>>
/\ \E proposal \in ValidValues \union {NilValue}:
\E vr \in RoundsOrNil:
BroadcastProposal(p, r, proposal, vr)
\//\ UNCHANGED <<msgsPropose, msgsPrecommit>>
/\ \E id \in ValidValues \union {NilValue}:
BroadcastPrevote(p, r, id)
\//\ UNCHANGED <<msgsPropose, msgsPrevote>>
/\ \E id \in ValidValues \union {NilValue}:
BroadcastPrecommit(p, r, id)
(******************************** PROPERTIES ***************************************)
\* simple reachability properties to see that the spec is progressing
NoPrevote == \A p \in Corr: step[p] /= "PREVOTE"
NoPrecommit == \A p \in Corr: step[p] /= "PRECOMMIT"
NoValidPrecommit ==
\A r \in Rounds:
\A m \in msgsPrecommit[r]:
m.id = NilValue \/ m.src \in Faulty
NoHigherRounds == \A p \in Corr: round[p] < 1
NoDecision == \A p \in Corr: decision[p] = NilValue
=============================================================================