├── .github └── workflows │ ├── apalache.yml │ └── tlatools.yml ├── .gitignore ├── .vscode └── settings.json ├── CITATION.cff ├── FPaxos.tla ├── LICENSE.md ├── MCFPaxos.cfg ├── MCFPaxosFourAcc.tla ├── MCFPaxosFourAccLarge.tla ├── MCFPaxosThreeAcc.tla ├── MCFPaxosTwoAcc.tla └── README.md /.github/workflows/apalache.yml: -------------------------------------------------------------------------------- 1 | name: Apalache 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - uses: actions/setup-java@v3 17 | with: 18 | distribution: 'microsoft' 19 | java-version: '17' 20 | - name: Setup 21 | run: | 22 | wget https://github.com/informalsystems/apalache/releases/latest/download/apalache.tgz 23 | tar zxvf apalache.tgz 24 | - name: Typecheck 25 | run: | 26 | ./apalache/bin/apalache-mc typecheck MCFPaxosTwoAcc.tla 27 | ./apalache/bin/apalache-mc typecheck MCFPaxosThreeAcc.tla 28 | ./apalache/bin/apalache-mc typecheck MCFPaxosFourAcc.tla 29 | - name: Check 30 | run: | 31 | ./apalache/bin/apalache-mc check --config=MCFPaxos.cfg MCFPaxosTwoAcc.tla 32 | ./apalache/bin/apalache-mc check --config=MCFPaxos.cfg MCFPaxosThreeAcc.tla 33 | ./apalache/bin/apalache-mc check --config=MCFPaxos.cfg MCFPaxosFourAcc.tla -------------------------------------------------------------------------------- /.github/workflows/tlatools.yml: -------------------------------------------------------------------------------- 1 | name: TLA+ Tools 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | branches: [ "main" ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - name: Install TLA+ Tools 16 | run: | 17 | git clone https://github.com/pmer/tla-bin.git 18 | cd tla-bin 19 | ./download_or_update_tla.sh 20 | sudo ./install.sh 21 | - name: Sany (All) 22 | run: sany *.tla 23 | - name: Exhaustive model checking with TLC - 2 Acceptors 24 | run: tlc -config MCFPaxos.cfg -workers auto MCFPaxosTwoAcc.tla 25 | - name: Exhaustive model checking with TLC - 3 Acceptors 26 | run: tlc -config MCFPaxos.cfg -workers auto MCFPaxosThreeAcc.tla 27 | - name: Exhaustive model checking with TLC - 4 Acceptors 28 | run: tlc -config MCFPaxos.cfg -workers auto MCFPaxosFourAcc.tla 29 | - name: Random exploration with TLC - 4 Acceptors 30 | run: tlc -config MCFPaxos.cfg -workers auto -simulate num=100 MCFPaxosFourAccLarge.tla 31 | - name: Install LaTeX 32 | run: sudo apt install texlive-latex-recommended 33 | - name: TLA+ pretty printer 34 | run: | 35 | tlatex FPaxos.tla 36 | pdflatex FPaxos.tex 37 | - name: Upload PDF file 38 | uses: actions/upload-artifact@v3 39 | with: 40 | name: Pretty Printed TLA+ Specification 41 | path: FPaxos.pdf -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## TLA+ 2 | states/ 3 | *.out 4 | _apalache-out 5 | *.log 6 | 7 | ## Ignore tex as automatically generated by tla+ pretty printer 8 | *.tex 9 | 10 | ## Core latex/pdflatex auxiliary files: 11 | *.aux 12 | *.lof 13 | *.log 14 | *.lot 15 | *.fls 16 | *.out 17 | *.toc 18 | *.fmt 19 | *.fot 20 | *.cb 21 | *.cb2 22 | .*.lb 23 | 24 | ## Intermediate documents: 25 | *.dvi 26 | *.xdv 27 | *-converted-to.* 28 | # these rules might exclude image files for figures etc. 29 | # *.ps 30 | # *.eps 31 | *.pdf 32 | 33 | ## Generated if empty string is given at "Please type another file name for output:" 34 | .pdf 35 | 36 | ## Bibliography auxiliary files (bibtex/biblatex/biber): 37 | *.bbl 38 | *.bcf 39 | *.blg 40 | *-blx.aux 41 | *-blx.bib 42 | *.run.xml 43 | 44 | ## Build tool auxiliary files: 45 | *.fdb_latexmk 46 | *.synctex 47 | *.synctex(busy) 48 | *.synctex.gz 49 | *.synctex.gz(busy) 50 | *.pdfsync 51 | 52 | ## Build tool directories for auxiliary files 53 | # latexrun 54 | latex.out/ 55 | 56 | ## Auxiliary and intermediate files from other packages: 57 | # algorithms 58 | *.alg 59 | *.loa 60 | 61 | # achemso 62 | acs-*.bib 63 | 64 | # amsthm 65 | *.thm 66 | 67 | # beamer 68 | *.nav 69 | *.pre 70 | *.snm 71 | *.vrb 72 | 73 | # changes 74 | *.soc 75 | 76 | # comment 77 | *.cut 78 | 79 | # cprotect 80 | *.cpt 81 | 82 | # elsarticle (documentclass of Elsevier journals) 83 | *.spl 84 | 85 | # endnotes 86 | *.ent 87 | 88 | # fixme 89 | *.lox 90 | 91 | # feynmf/feynmp 92 | *.mf 93 | *.mp 94 | *.t[1-9] 95 | *.t[1-9][0-9] 96 | *.tfm 97 | 98 | #(r)(e)ledmac/(r)(e)ledpar 99 | *.end 100 | *.?end 101 | *.[1-9] 102 | *.[1-9][0-9] 103 | *.[1-9][0-9][0-9] 104 | *.[1-9]R 105 | *.[1-9][0-9]R 106 | *.[1-9][0-9][0-9]R 107 | *.eledsec[1-9] 108 | *.eledsec[1-9]R 109 | *.eledsec[1-9][0-9] 110 | *.eledsec[1-9][0-9]R 111 | *.eledsec[1-9][0-9][0-9] 112 | *.eledsec[1-9][0-9][0-9]R 113 | 114 | # glossaries 115 | *.acn 116 | *.acr 117 | *.glg 118 | *.glo 119 | *.gls 120 | *.glsdefs 121 | *.lzo 122 | *.lzs 123 | *.slg 124 | *.slo 125 | *.sls 126 | 127 | # uncomment this for glossaries-extra (will ignore makeindex's style files!) 128 | # *.ist 129 | 130 | # gnuplot 131 | *.gnuplot 132 | *.table 133 | 134 | # gnuplottex 135 | *-gnuplottex-* 136 | 137 | # gregoriotex 138 | *.gaux 139 | *.glog 140 | *.gtex 141 | 142 | # htlatex 143 | *.4ct 144 | *.4tc 145 | *.idv 146 | *.lg 147 | *.trc 148 | *.xref 149 | 150 | # hyperref 151 | *.brf 152 | 153 | # knitr 154 | *-concordance.tex 155 | # TODO Uncomment the next line if you use knitr and want to ignore its generated tikz files 156 | # *.tikz 157 | *-tikzDictionary 158 | 159 | # listings 160 | *.lol 161 | 162 | # luatexja-ruby 163 | *.ltjruby 164 | 165 | # makeidx 166 | *.idx 167 | *.ilg 168 | *.ind 169 | 170 | # minitoc 171 | *.maf 172 | *.mlf 173 | *.mlt 174 | *.mtc[0-9]* 175 | *.slf[0-9]* 176 | *.slt[0-9]* 177 | *.stc[0-9]* 178 | 179 | # minted 180 | _minted* 181 | *.pyg 182 | 183 | # morewrites 184 | *.mw 185 | 186 | # newpax 187 | *.newpax 188 | 189 | # nomencl 190 | *.nlg 191 | *.nlo 192 | *.nls 193 | 194 | # pax 195 | *.pax 196 | 197 | # pdfpcnotes 198 | *.pdfpc 199 | 200 | # sagetex 201 | *.sagetex.sage 202 | *.sagetex.py 203 | *.sagetex.scmd 204 | 205 | # scrwfile 206 | *.wrt 207 | 208 | # svg 209 | svg-inkscape/ 210 | 211 | # sympy 212 | *.sout 213 | *.sympy 214 | sympy-plots-for-*.tex/ 215 | 216 | # pdfcomment 217 | *.upa 218 | *.upb 219 | 220 | # pythontex 221 | *.pytxcode 222 | pythontex-files-*/ 223 | 224 | # tcolorbox 225 | *.listing 226 | 227 | # thmtools 228 | *.loe 229 | 230 | # TikZ & PGF 231 | *.dpth 232 | *.md5 233 | *.auxlock 234 | 235 | # titletoc 236 | *.ptc 237 | 238 | # todonotes 239 | *.tdo 240 | 241 | # vhistory 242 | *.hst 243 | *.ver 244 | 245 | # easy-todo 246 | *.lod 247 | 248 | # xcolor 249 | *.xcp 250 | 251 | # xmpincl 252 | *.xmpi 253 | 254 | # xindy 255 | *.xdy 256 | 257 | # xypic precompiled matrices and outlines 258 | *.xyc 259 | *.xyd 260 | 261 | # endfloat 262 | *.ttt 263 | *.fff 264 | 265 | # Latexian 266 | TSWLatexianTemp* 267 | 268 | ## Editors: 269 | # WinEdt 270 | *.bak 271 | *.sav 272 | 273 | # Texpad 274 | .texpadtmp 275 | 276 | # LyX 277 | *.lyx~ 278 | 279 | # Kile 280 | *.backup 281 | 282 | # gummi 283 | .*.swp 284 | 285 | # KBibTeX 286 | *~[0-9]* 287 | 288 | # TeXnicCenter 289 | *.tps 290 | 291 | # auto folder when using emacs and auctex 292 | ./auto/* 293 | *.el 294 | 295 | # expex forward references with \gathertags 296 | *-tags.tex 297 | 298 | # standalone packages 299 | *.sta 300 | 301 | # Makeindex log files 302 | *.lpz 303 | 304 | # xwatermark package 305 | *.xwm 306 | 307 | # REVTeX puts footnotes in the bibliography by default, unless the nofootinbib 308 | # option is specified. Footnotes are the stored in a file with suffix Notes.bib. 309 | # Uncomment the next line to have this generated file ignored. 310 | #*Notes.bib -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "tlaplus.tlc.modelChecker.options": "-coverage 1 -workers auto" 3 | } -------------------------------------------------------------------------------- /CITATION.cff: -------------------------------------------------------------------------------- 1 | cff-version: 1.2.0 2 | title: TLA+ Specification of Flexible Paxos 3 | message: >- 4 | If you use this specification, please cite it using the 5 | metadata from this file. 6 | type: software 7 | authors: 8 | - given-names: Heidi 9 | family-names: Howard 10 | repository-code: 'https://github.com/fpaxos/fpaxos-tlaplus' 11 | license: MIT 12 | preferred-citation: 13 | type: conference-paper 14 | authors: 15 | - family-names: Howard 16 | given-names: Heidi 17 | - family-names: Malkhi 18 | given-names: Dahlia 19 | - family-names: Spiegelman 20 | given-names: Alexander 21 | doi: "10.4230/LIPIcs.OPODIS.2016.25" 22 | conference: 23 | name: "20th International Conference on Principles of Distributed Systems (OPODIS 2016)" 24 | month: 9 25 | title: "Flexible Paxos: Quorum Intersection Revisited" 26 | volume: 70 27 | year: 2017 -------------------------------------------------------------------------------- /FPaxos.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE FPaxos ---- 2 | 3 | EXTENDS Integers, FiniteSets 4 | 5 | CONSTANT 6 | \* @type: Set(Int); 7 | Value, 8 | \* @type: Set(Str); 9 | Acceptor, 10 | \* @type: Set(Set(Str)); 11 | Quorum1, 12 | \* @type: Set(Set(Str)); 13 | Quorum2, 14 | \* @type: Set(Int); 15 | Ballot 16 | 17 | ASSUME QuorumAssumption == 18 | /\ \A Q \in Quorum1 : Q \subseteq Acceptor 19 | /\ \A Q \in Quorum2 : Q \subseteq Acceptor 20 | /\ \A Q1 \in Quorum1 : \A Q2 \in Quorum2 : Q1 \cap Q2 # {} 21 | 22 | VARIABLE 23 | \* @type: Str -> Int; 24 | maxBal, 25 | \* @type: Str -> Int; 26 | maxVBal, 27 | \* @type: Str -> Int; 28 | maxVal, 29 | \* @type: Set({bal: Int}); 30 | 1aMsgs, 31 | \* @type: Set({bal: Int, mbal: Int, acc: Str, mval: Int}); 32 | 1bMsgs, 33 | \* @type: Set({bal: Int, val: Int}); 34 | 2aMsgs, 35 | \* @type: Set({bal: Int, acc: Str, val: Int}); 36 | 2bMsgs 37 | 38 | msgs == <<1aMsgs, 1bMsgs, 2aMsgs, 2bMsgs>> 39 | vars == <> 40 | 41 | TypeOK == 42 | /\ maxBal \in [Acceptor -> Ballot \cup {-1}] 43 | /\ maxVBal \in [Acceptor -> Ballot \cup {-1}] 44 | /\ maxVal \in [Acceptor -> Value \cup {-1}] 45 | /\ 1aMsgs \in SUBSET [bal : Ballot] 46 | /\ 1bMsgs \in SUBSET [acc : Acceptor, bal : Ballot, mbal : Ballot \cup {-1}, mval : Value \cup {-1}] 47 | /\ 2aMsgs \in SUBSET [bal : Ballot, val : Value] 48 | /\ 2bMsgs \in SUBSET [acc : Acceptor, bal : Ballot, val : Value] 49 | 50 | Init == 51 | /\ maxBal = [a \in Acceptor |-> -1] 52 | /\ maxVBal = [a \in Acceptor |-> -1] 53 | /\ maxVal = [a \in Acceptor |-> -1] 54 | /\ 1aMsgs = {} 55 | /\ 1bMsgs = {} 56 | /\ 2aMsgs = {} 57 | /\ 2bMsgs = {} 58 | 59 | Phase1a(b) == 60 | /\ 1aMsgs' = 1aMsgs \union {[bal |-> b]} 61 | /\ UNCHANGED <> 62 | 63 | Phase1b(a) == 64 | /\ \E m \in 1aMsgs : 65 | /\ m.bal > maxBal[a] 66 | /\ maxBal' = [maxBal EXCEPT ![a] = m.bal] 67 | /\ 1bMsgs' = 1bMsgs \union {[acc |-> a, bal |-> m.bal, mbal |-> maxVBal[a], mval |-> maxVal[a]]} 68 | /\ UNCHANGED <> 69 | 70 | Phase2a(b, v) == 71 | /\ ~ \E m \in 2aMsgs : m.bal = b 72 | /\ \E Q \in Quorum1 : 73 | LET Q1b == {m \in 1bMsgs : /\ m.acc \in Q 74 | /\ m.bal = b} 75 | Q1bv == {m \in Q1b : m.mbal \geq 0} 76 | IN /\ \A a \in Q : \E m \in Q1b : m.acc = a 77 | /\ \/ Q1bv = {} 78 | \/ \E m \in Q1bv : 79 | /\ m.mval = v 80 | /\ \A mm \in Q1bv : m.mbal \geq mm.mbal 81 | /\ 2aMsgs' = 2aMsgs \union {[bal |-> b, val |-> v]} 82 | /\ UNCHANGED <> 83 | 84 | Phase2b(a) == 85 | /\ \E m \in 2aMsgs : 86 | /\ m.bal \geq maxBal[a] 87 | /\ maxBal' = [maxBal EXCEPT ![a] = m.bal] 88 | /\ maxVBal' = [maxVBal EXCEPT ![a] = m.bal] 89 | /\ maxVal' = [maxVal EXCEPT ![a] = m.val] 90 | /\ 2bMsgs' = 2bMsgs \union {[acc |-> a, bal |-> m.bal, val |-> m.val]} 91 | /\ UNCHANGED <<1aMsgs, 1bMsgs, 2aMsgs>> 92 | 93 | Next == 94 | \/ \E b \in Ballot : \/ Phase1a(b) 95 | \/ \E v \in Value : Phase2a(b, v) 96 | \/ \E a \in Acceptor : Phase1b(a) \/ Phase2b(a) 97 | 98 | Spec == Init /\ [][Next]_vars 99 | 100 | Sent2b(a,v,b) == 101 | \E m \in 2bMsgs: 102 | /\ m.acc = a 103 | /\ m.val = v 104 | /\ m.bal = b 105 | 106 | Sent2a(v,b) == 107 | \E m \in 2aMsgs: 108 | /\ m.val = v 109 | /\ m.bal = b 110 | 111 | Agreed(v,b) == 112 | \E Q \in Quorum2: 113 | \A a \in Q: Sent2b(a,v,b) 114 | 115 | Decided(v) == 116 | \A b \in Ballot: Agreed(v,b) 117 | 118 | NoFutureProposal(v,b) == 119 | \A v2 \in Value: 120 | \A b2 \in Ballot: (b2 > b /\ Sent2a(v2,b2)) => v=v2 121 | 122 | SafeValue == 123 | \A v \in Value: 124 | \A b \in Ballot: Agreed(v,b) => NoFutureProposal(v,b) 125 | 126 | Safety == Cardinality({ v \in Value: Decided(v) }) \leq 1 127 | 128 | \* Below is my first attempt at a inductive invariant. Not currently working 129 | 130 | OneValueAgreedPerBallot == 131 | \A b \in Ballot: Cardinality({ v \in Value: Agreed(v,b) }) \leq 1 132 | 133 | OneVotePerAcceptorPerBallot == 134 | \A a \in Acceptor: 135 | \A b \in Ballot: Cardinality({ v \in Value: Sent2b(a,v,b) }) \leq 1 136 | 137 | SafeStates == 138 | \A a \in Acceptor: 139 | /\ \/ maxBal[a] = -1 140 | \/ \E m \in 1aMsgs: m.bal = maxBal[a] 141 | \/ \E m \in 2aMsgs: m.bal = maxBal[a] 142 | /\ maxBal[a] >= maxVBal[a] 143 | /\ \A m \in 1bMsgs: 144 | /\ m.acc = a 145 | => /\ m.bal <= maxBal[a] 146 | /\ m.mbal <= maxVBal[a] 147 | /\ \A m \in 2bMsgs: 148 | /\ m.acc = a 149 | => /\ m.bal <= maxBal[a] 150 | /\ m.bal <= maxVBal[a] 151 | /\ \/ (maxVBal[a] = -1 /\ maxVal[a] = -1) 152 | \/ \E m \in 2aMsgs: 153 | /\ m.bal = maxVBal[a] 154 | /\ m.val = maxVal[a] 155 | 156 | 157 | Safe1b == 158 | \A m \in 1bMsgs: 159 | /\ \E a \in Acceptor: 160 | /\ m.acc = a 161 | /\ \/ /\ m.mbal = -1 162 | /\ m.mval = -1 163 | \* acceptor $a$ never accepted a proposal in a smaller ballot 164 | /\ ~ \E m2 \in 2bMsgs: 165 | /\ m2.acc = a 166 | /\ m2.bal < m.bal 167 | /\ \A m2 \in 1bMsgs: 168 | /\ m2.acc = a 169 | /\ m2.bal < m.bal 170 | => m2.mbal = -1 /\ m2.mval = -1 171 | \/ \E m2 \in 2aMsgs: 172 | /\ m.mbal = m2.bal 173 | /\ m.mval = m2.val 174 | /\ m.bal > m.mbal 175 | /\ \A m2 \in 1bMsgs: 176 | /\ m2.mbal = m.mbal 177 | => m2.mval = m.mval 178 | 179 | Safe2a == 180 | \A m \in 2aMsgs: 181 | /\ \E Q \in Quorum1: 182 | \E a_max \in Q: 183 | \E bal_max \in Ballot \cup {-1}: 184 | /\ \E m_max \in 1bMsgs: 185 | /\ m_max.acc = a_max 186 | /\ m_max.bal = m.bal 187 | /\ m_max.mbal = bal_max 188 | /\ \/ bal_max = -1 189 | \/ m_max.mval = m.val 190 | /\ \A a2 \in Q: 191 | \E m2 \in 1bMsgs: 192 | /\ m2.acc = a2 193 | /\ m2.bal = m.bal 194 | /\ bal_max \geq m2.mbal 195 | /\ \A m2 \in 2aMsgs: 196 | /\ m2.bal = m.bal 197 | => m2.val = m.val 198 | 199 | Safe2b == 200 | \A m \in 2bMsgs: 201 | /\ \E a \in Acceptor: 202 | /\ m.acc = a 203 | /\ \/ /\ maxBal[a] \geq m.bal 204 | /\ maxVBal[a] = m.bal 205 | /\ maxVal[a] = m.val 206 | \/ m.bal < maxBal[a] 207 | /\ \E m2 \in 2aMsgs: 208 | /\ m2.bal = m.bal 209 | /\ m2.val = m.val 210 | 211 | 212 | Inv == 213 | /\ TypeOK 214 | /\ SafeStates 215 | /\ Safe1b 216 | /\ Safe2a 217 | /\ Safe2b 218 | /\ SafeValue 219 | /\ Safety 220 | 221 | ==== -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | This TLA+ specification is derived from [TLA+ examples](https://github.com/tlaplus/Examples), both are licensed under the MIT License. 2 | 3 | Copyright (c) 2016: Heidi Howard 4 | 5 | > Copyright (c) 2016: The TLA+ project and other contributors: 6 | > https://github.com/tlaplus/Examples/graphs/contributors 7 | > 8 | > 9 | > Permission is hereby granted, free of charge, to any person obtaining 10 | > a copy of this software and associated documentation files (the 11 | > "Software"), to deal in the Software without restriction, including 12 | > without limitation the rights to use, copy, modify, merge, publish, 13 | > distribute, sublicense, and/or sell copies of the Software, and to 14 | > permit persons to whom the Software is furnished to do so, subject to 15 | > the following conditions: 16 | > 17 | > The above copyright notice and this permission notice shall be 18 | > included in all copies or substantial portions of the Software. 19 | > 20 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 | > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 | > NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 | > LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 | > OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 | > WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | -------------------------------------------------------------------------------- /MCFPaxos.cfg: -------------------------------------------------------------------------------- 1 | SPECIFICATION Spec 2 | CONSTANTS 3 | Acceptor <- MCAcceptor 4 | Value <- MCValue 5 | Quorum1 <- MCQuorum1 6 | Quorum2 <- MCQuorum2 7 | Ballot <- MCBallot 8 | None = None 9 | 10 | INVARIANT SafeValue TypeOK 11 | -------------------------------------------------------------------------------- /MCFPaxosFourAcc.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE MCFPaxosFourAcc ---- 2 | 3 | EXTENDS FPaxos, TLC 4 | 5 | MCAcceptor == {"a1", "a2", "a3", "a4"} 6 | MCValue == 0..2 7 | MCQuorum1 == {{"a1", "a2"}, {"a3", "a4"}} 8 | MCQuorum2 == {{"a1", "a3"}, {"a2", "a4"}} 9 | MCBallot == 0..2 10 | 11 | ==== -------------------------------------------------------------------------------- /MCFPaxosFourAccLarge.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE MCFPaxosFourAccLarge ---- 2 | 3 | EXTENDS FPaxos, TLC 4 | 5 | MCAcceptor == {"a1", "a2", "a3", "a4"} 6 | MCValue == 0..10 7 | MCQuorum1 == {{"a1", "a2"}, {"a3", "a4"}} 8 | MCQuorum2 == {{"a1", "a3"}, {"a2", "a4"}} 9 | MCBallot == 0..10 10 | 11 | ==== -------------------------------------------------------------------------------- /MCFPaxosThreeAcc.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE MCFPaxosThreeAcc ---- 2 | 3 | EXTENDS FPaxos, TLC 4 | 5 | MCAcceptor == {"a1", "a2", "a3"} 6 | MCValue == 0..2 7 | MCQuorum1 == {{"a1", "a2"}, {"a1", "a3"}, {"a2", "a3"}} 8 | MCQuorum2 == {{"a1", "a2"}, {"a1", "a3"}, {"a2", "a3"}} 9 | MCBallot == 0..2 10 | 11 | ==== -------------------------------------------------------------------------------- /MCFPaxosTwoAcc.tla: -------------------------------------------------------------------------------- 1 | ---- MODULE MCFPaxosTwoAcc ---- 2 | 3 | EXTENDS FPaxos, TLC 4 | 5 | MCAcceptor == {"a1", "a2"} 6 | MCValue == 0..2 7 | MCQuorum1 == {{"a1"}, {"a2"}} 8 | MCQuorum2 == {{"a1", "a2"}} 9 | MCBallot == 0..2 10 | 11 | ==== -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TLA+ Specification of Flexible Paxos 2 | 3 | This repository contains the [TLA+](research.microsoft.com/en-us/um/people/lamport/tla/tla.html) specification and TLC model checking configuration for single shot [Flexible Paxos](http://drops.dagstuhl.de/opus/volltexte/2017/7094/pdf/LIPIcs-OPODIS-2016-25.pdf). 4 | 5 | Instructions for installing and setting up TLA+ are available [elsewhere](http://research.microsoft.com/en-us/um/people/lamport/tla/tla.html). These instructions assume that you are running TLA+ from the command line using [tla-bin](https://github.com/pmer/tla-bin). 6 | 7 | You can model check this specification by cloning this directory and running: 8 | ``` 9 | $ tlc -config MCFPaxos.cfg MCFPaxosTwoAcc.tla 10 | ``` 11 | 12 | By editing [MCFPaxosTwoAcc.tla](MCFPaxosTwoAcc.tla), you can modify the configuration to test different models. For example, you might wish to try changing the number of acceptors, how quorums are composed or the number of ballots. 13 | 14 | This TLA+ specification is derived from [Leslie Lamport's](http://www.lamport.org) Paxos specification from [TLA+ Examples](https://github.com/tlaplus/Examples). 15 | --------------------------------------------------------------------------------