├── tla
├── .gitignore
├── Atomic.tla
└── Universal.tla
├── figures
├── connector.pdf
├── parallel-path.pdf
├── payment-chain.pdf
├── sender-trust.pdf
├── three-bells.pdf
├── atomic-sequence.pdf
├── recipient-trust.pdf
├── transfer-states.pdf
├── web-of-ledgers.pdf
├── connector-escrow.pdf
├── settlement-trust.pdf
├── universal-sequence.pdf
├── connector-execution.pdf
├── transfer-states.xml
├── connector-execution.xml
├── connector-escrow.xml
├── parallel-path.xml
├── three-bells.xml
├── sender-trust.xml
├── recipient-trust.xml
├── settlement-trust.xml
├── connector.xml
├── payment-chain.xml
├── web-of-ledgers.xml
└── universal-sequence.xml
├── README.md
├── specs
├── ilpspec.sty
├── atomic.tex
└── universal.tex
├── usenix.sty
├── interledger.bib
└── acm.bst
/tla/.gitignore:
--------------------------------------------------------------------------------
1 | *.pdf
2 | *.toolbox
3 |
--------------------------------------------------------------------------------
/figures/connector.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/connector.pdf
--------------------------------------------------------------------------------
/figures/parallel-path.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/parallel-path.pdf
--------------------------------------------------------------------------------
/figures/payment-chain.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/payment-chain.pdf
--------------------------------------------------------------------------------
/figures/sender-trust.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/sender-trust.pdf
--------------------------------------------------------------------------------
/figures/three-bells.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/three-bells.pdf
--------------------------------------------------------------------------------
/figures/atomic-sequence.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/atomic-sequence.pdf
--------------------------------------------------------------------------------
/figures/recipient-trust.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/recipient-trust.pdf
--------------------------------------------------------------------------------
/figures/transfer-states.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/transfer-states.pdf
--------------------------------------------------------------------------------
/figures/web-of-ledgers.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/web-of-ledgers.pdf
--------------------------------------------------------------------------------
/figures/connector-escrow.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/connector-escrow.pdf
--------------------------------------------------------------------------------
/figures/settlement-trust.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/settlement-trust.pdf
--------------------------------------------------------------------------------
/figures/universal-sequence.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/universal-sequence.pdf
--------------------------------------------------------------------------------
/figures/connector-execution.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/interledger/paper/HEAD/figures/connector-execution.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # The Interledger Protocol White Paper
2 | This folder contains the files used to publish the ILP white paper that can be downloaded as a PDF from http://interledger.org
3 |
4 | ## Contributions
5 | Please feel free to log issues or submit PRs to the editors
6 |
--------------------------------------------------------------------------------
/figures/transfer-states.xml:
--------------------------------------------------------------------------------
1 | zZbNctowEMefxnewSIFjoDS9dCZTDj0r9sbWRPZ6ZDlAnz6StUI2UOq0aY0PjPXXaj9+ixYiti72D4pX+TdMQUbxJN1H7HMUx/PlzHxa4eCE2eKTEzIlUidNg7AVP4HECamNSKHuGWpEqUXVFxMsS0h0T3tG2Q9R8cy7D8I24fJc/SFSnVPKE8rF6l9BZLkPE9PGE09eMoVNSeGimD23j9suuHfV2rON4aUQjRf7VuzXIC0zz8M5/fKL3WOOCkrK4/oBs2UPvHLZUJmPCiusIXUbtT74+ne50LCteGLXO9PPiK1yXUizmprX88iUzCsoDdTxVqJMHgAL0OpgTPwuEaNvg1/uAu2pp513SM9I49T07Og4FG5eqPbLHNgFDmCLGYXD3Xgg6EZ2QGz2kDR6FBDxcjwQd2cg7p/QJH4LHOb/kQNN5E69kJq5SEtTk9CH7yC5Flhuws6qnXiGloPQ4VFrhS+wRomq9ccm7XONVI2NaumGiaW5yoCs6PLavAZdr5M5wz6A0vzGKBGSLiW62UMpxSdD6CMoLa5SMrcrxwxLLkciRFf+XxBqndwrxe15b1ChKHXdifFohU4Af8/7AY6/5b8xX7h6Qm9c/NCpY0mDmre8oeZdGALvbN57hsAfNW/qPQ5r3qn53zXPLMN/SGce/oCzzRs=
--------------------------------------------------------------------------------
/figures/connector-execution.xml:
--------------------------------------------------------------------------------
1 | 7VrNc+o2EP9rOD7GQsTAMaFpe2hn3jSH9h2NrdiaJywqTD76179da2XLNiae4IZMXjgAWq1Wuz+t90Mw4evt028m2mV/6kSoySxInib8l8lsxuZ8Dh9IebaURRhaQmpkQkw14U7+J4gYEPUgE7FvMBZaq0LumsRY57mIiwbtXqvmFrsodeJrwl0cqS71b5kUmaXyJemC9N+FTDO3jZvYRPH31OhDTttNZvy+fNnpbeRElfz8FgAzWoMU/LZ9WguFoDk8rNBfe2YrHY3ISY/TC2AKFzxE6kBmWsK+eHZ2wwLAEwY3j5ksxN0uinHmEY4UaFmxVTBi8LW7N6nzIEwh3KFXRoJXCL0VhXkGFprlhBn5AykfPNZ4z4mUeVA7WkSnnlZya8vhCxl/HAjeAeJO5IkwHTjAEtjWt3tfGP1drLXSBii5zhGre6lUixQpmeYwjAEfEMxvEBcJDnZNE1uZJLjNUaA1cN8r/QiUDPgELBgDcfcoEeLsqgu5c2Qfcncy50BOD78H+do+pwDaR0fdwXwB2K+OPPKhQnSLaANAQMTSBj0f58J/DxiKbsAc97WhZTUfgGYg2WOqT88Radk1TDr+wPI6G49MWWW+xFqpqAxDyFONvA3DlD6tLRsNWaVNBMdqURJEkzyhlkbO0pEOPgPeQWsBaFx+lkAw9YQwJHZVPteI231swKNHtKI8spHs6LoNPvtfSJny8Hu0WGdKDzic128wmpFNyqbD06v8qxYeVQyJxx4RpNsw4OgvRmIvRmL8HSdCuuhHAXJgfHS0c+IjlaB+BZRAIUhDyiplPSdwBYYpDwzxJIt/vO/fkGV6haMcFMEpXFEO6rlewPb6YMp8VNdqRWRSQVwLS0IFh4C6WE6hxoYqa7WYzRlfUQauklA/eCTyq5agYC1vNQ0ZCxm/YnzJliEpTfL4crqCd2ALYFe+IP2deGsaSfRL1NYmHIOLL3bVlGPx6Mgpj7mCYNDJE5rvpRhmi4tVwwSxh8RfIpY7icZ88NJstrpcacactqc8ME+uDeZvwE1F+72MWwEod43y3A86dqoKOnxRhaSvwkjQtCz4MDTFB/NQRrZGOJsGAYDmhTQGNZodtwX0HsKLYcqD2KHuQ+xoRqiokA/Nvnx41GJh84TbSWNoYGrLKaugAZEJji9Cax3bDhn2J/Rt5UJy0NqnrMDXRj323u4AWi3pG4Y9RrcA7yP3D83q4CDjpvX2pUAb2sGZ+wU542Vu1r1L+Gxqh3ZvA/umz6b2Ek3tjd58trQfo6WtMtnb97SMmtpTOV7JMrsl0sAVrNT4kECgR826tb37AWSsTmdJOao/5btUMnrK7zZ9f2Di/fBX0K2i8k3bnOVPink7Arwp6N2e/qfqLXtukxzcA1vP4UV030bnXn/9X10mb/nmeV0mDOsfsS17/RcAfvsD
--------------------------------------------------------------------------------
/figures/connector-escrow.xml:
--------------------------------------------------------------------------------
1 | 7VrPc+o2EP5rOD7GRsTAMaFpe2hnMi+HtkdhK1jzhEVlkx/969+utbJlGxNPcJNXGg6AVtJq99P6065gwta7518M36e/60SoySxInifsp8lsFs7ZHD5Q8mIliyiygq2RCQ2qBffyH0HCgKQHmYi8MbDQWhVy3xTGOstEXDRkD1o1l9jzrVNfC+5jrrrSP2RSpFbKlmQLyn8Vcpu6ZVzHhsfftkYfMlpuMmMP5ct277hTVY5ntwCY0Rq04Lfd81ooBM3hYZX+3NNb2WhERnacngBdOOGRqwO5aQV58eL8hgmAJzRunlJZiPs9j7HnCbYUZGmxU9AK4Wt3bTLnUZhCuE2vnISoEHonCvMCQ6iXEWYUD2R88FTjPSdR6kHtZJx2fVvprT2HL+T8cSBYB4h7kSXCdOAAT2BZ3++8MPqbWGulDUgynSFWD1Kplogruc2gGQM+oJjdIC4SAuyaOnYySXCZo0BrGP2g9BNIUhgnYMIYiLtHiRAPr7qQu0D2IXc7cw7k9PB7kK/tcwqgXTrqDuYPgP3qyCMfKUS34BsAAhhLG4x87Iv+PiAV3YA77mvDyqo/AMtAszeo3j0npGnX0OnGB3as8/FIlzXmS6yV4iUN4Ziq5S0YbenT+rLRcKq0hRBYLUmCaFIk1NooWDraIWYgOmguAI3Tz1JYOntCHQq7Rp/rxm0eG4jpEf0Yz4tu2OCz/4VMKTe/x4Z1qvSAzXn7AqM52ZRsOmN6jX/TxKOGofDYI4JySwNO/ioTexyJ/DsOQzr2I4IcyI9Odg4/UgrqZ0AJJILUpFOlzOcEzkCa8sAQz7L40/v+Fw6ZXmErA0OwC2eUjbov4XlaasNp2LjjBYQgPnsAUzA/hWmuD6Y8sup0ruBmK2jUworQhyG4L5ZTSMMhEVstZvOQreiQrs6pfnxJ5Z2WYGCtbzWNwjAK2VXIluEyIqNJH1tOV/AOwwJYlS3IfqfeukYa/Sy2tQhDFvXVrpp6LB4dPWUkVBAMCg5C80fJl8PFhyXMBLGHxFcRy71EZy48e5utPi57C521pyIwS64NHvCAm+J5LuMWR2WulkZiqXjJdlW8xBYVa90JI8HSMidE9ooP5rGiq4rxpkEAoHmsF0IaZ9ttBYPIjLjGJzMSvUpm3ka4vfE3wsmMULyQj80Cfzi3Vc8RxUHU2t+h9FXZQ3rap1gPfcEec3TWDdvjgLzf3OpGwt22NK4G4ItV+FZqDH+0u4RWafuO3BjSbcJ/JocYmh1ADI2bHrTvH9roD84AXtEzXgYQdq8tPuvnoWXiwBLts37+iPr5Rm8+q+fLqJ6rw+79y+eQ6udTaYCS5QGYSAO3vVLjIwJEj5Z1awT3W8tYFdOSzqj+rMAdJaNnBd3i8Tc8eC/+truVd75rubT8n2LeZoB3Bb17N3BJNerQZLl9K+XKw4HF6fAkum+hc6/R/qU6lLVC87w6FJr1z+V2eP1nA3b7HQ==
--------------------------------------------------------------------------------
/figures/parallel-path.xml:
--------------------------------------------------------------------------------
1 | 7Vtdd+I2E/41uUwOtgkkl4F3d3vRnrOnuWh76dgK6FQgXmHy0V+/I2vGliUMAhyT0r0BPJZG8/HMaEY2V8l08fZNpav5bzJn4ioe5G9Xyf+u4ng4voNPTXgnwq0hzBTPDSmqCY/8H4bEAVI3PGfrxsBCSlHwVZOYyeWSZUWD9ixFc4lVOiP2NeExS4VP/YPnxdxQkzuURdN/YXw2x2XiGG+si3dikbPndCOK65IE9/TtRUqsyvHJF7CXkhK46F+LtykT2mZkD8P0a8vdSkbFlijH7gmJmfCSig3K+MiWOVOe6AV7A4aTebEQQIjg57pQ8m82lUIqoCzlEkZOnrkQDikVfLaEywxEAsbJ5IWpgoNdH/DGgue5XmbyOucFe1ylmV7zFRADNAmjn4V8BcocxjGYMPGVRL01Z4bgKkmo9DcmF6xQ7zCE7qJzEHjXCV6/1p4lx85tpyItRXzNKsa1jeEHmnm7yYeeyacGnlKtL97st+ezO6YWy+5X8Uho6xbpExgiHjxJpaGv743+v9EhOAF16GdDyur+ACQDztag2ntExGkPcJPGD8xY0nHLLSPMdSaFSFdrYKjHVFfWgqMZfhtdniRkU5cI8exQcm1NRELNDcHicQfMADpwLhhaTz+JYansDnaa6At9qhrTuZCdqtGdEj5qdOhfoyil71uVUhwSxz6ljl+gMyWblCdvTKvwR03cKpgmbosQTTdZgOh7E7GVInX67SZBUvKj/BgFJkiinZIgR57SLIcKCC9xW1FyA/WBnqHzlGUO0Fm9/4n08uIvfXFzu8swRapmDEljQ9JrhlhqfHcTj0dxMrgfx8MoucdttTLcCPP9Nosg0++Sgzz15kS7TCuPtdyojOE0u6pyOCU6uzU4DVFh4mQU9ziVLqp0DfLavbet/c4yvuLa1BdeTcT356smIpLWLifc8FnmD0qVamciXa955oYM9TRDO4CqaDIBlEBThITvTHGQtKxRdJhlG/VSxmI55Y0X5fSbwQCMVl4bDhGUFebaZdDqBIP0RuFkxyqS9saq5Qiq/GxHEE0xkRb8pdlohQduPHTDzfVwaOBWElWcKJL3BC74OdUK07CVHlCW8y25ZuwuhB1JDT/D8ti0EGFnd2w2JzA1gGSAWIEamQDla7kB7oZUaGKPo84zu9fuRYSYgwEy2rdHdJfZI79T/NmxnK3U144/Q8MSVNuHM9S4P3vHMpFPP/uVy+hXqlrqHA1LhC2DlSB/1bvMxZ9eul1in3UvHtn/52zuIb1Ho2/rLfpszUmH0BJutLuCiwdn7M0jr4JzU1F3FRw9Xvk8Rbjd1x3qVcD3brdGhxfmnluppf/MhfnWRwkH9v6109s93d63t50VjMyMbWcFl9Hqew+Q6PpgvHhHdB/V6XtHurhQV50+HZxe6ElUaHbyz1yJEIjMcBC2L3XyQXHgXnQoCBP3AATTbGcY9KvCf3FGPB5ytJ31ALljjzh7g5y3tXed9/wnHx7mZgCqVUulX70WVPbR1rsyPiR2IMCtJXG7tABQGcJGgHv+eFRXEBBzQsC7UG2dkhV8vuKVefd3SJaypFfXukafRlmqHyhselA+CVHe6whCGwmvbXDS33ZLNRqJc1aETkEYoXyHpkXnUaKbXbtrHpJtp/qHl2votbD2PsijdtFvwi34LISM3vm25ybYo5/rOUW4i5IO3YsLnXNX8h4uVs+/ekhWJO4HZerKvp9iW6qOEXcoK3iZjnOuwKtc6vNLgK2WzD8bpReLT9a9apc9vxMUOt+kAkzRO/Crw74esBDShp+A+/AD6z7KMXxXrCfcH/Ge8UfhHi7rt/PN/lD/tSH58gM=
--------------------------------------------------------------------------------
/specs/ilpspec.sty:
--------------------------------------------------------------------------------
1 |
2 | %
3 | % USENIX wants margins of: 1" sides, 1" bottom, and 1" top.
4 | % 0.25" gutter between columns.
5 | % Gives active areas of 6.5" x 9"
6 | %
7 | \setlength{\textheight}{9.0in}
8 | \setlength{\columnsep}{0.25in}
9 | \setlength{\textwidth}{6.50in}
10 |
11 | \setlength{\topmargin}{0.0in}
12 |
13 | \setlength{\headheight}{0.0in}
14 |
15 | \setlength{\headsep}{0.0in}
16 |
17 | % Usenix wants no page numbers for camera-ready papers, so that they can
18 | % number them themselves. But submitted papers should have page numbers
19 | % for the reviewers' convenience.
20 | %
21 | %
22 | % \pagestyle{empty}
23 |
24 | %
25 | % Usenix titles are in 14-point bold type, with no date, and with no
26 | % change in the empty page headers. The whole author section is 12 point
27 | % italic--- you must use {\rm } around the actual author names to get
28 | % them in roman.
29 | %
30 | \def\maketitle{\par
31 | \begingroup
32 | \renewcommand\thefootnote{\fnsymbol{footnote}}%
33 | \def\@makefnmark{\hbox to\z@{$\m@th^{\@thefnmark}$\hss}}%
34 | \long\def\@makefntext##1{\parindent 1em\noindent
35 | \hbox to1.8em{\hss$\m@th^{\@thefnmark}$}##1}%
36 | \if@twocolumn
37 | \twocolumn[\@maketitle]%
38 | \else \newpage
39 | \global\@topnum\z@
40 | \@maketitle \fi\@thanks
41 | \endgroup
42 | \setcounter{footnote}{0}%
43 | \let\maketitle\relax
44 | \let\@maketitle\relax
45 | \gdef\@thanks{}\gdef\@author{}\gdef\@title{}\let\thanks\relax}
46 |
47 | \def\@maketitle{\newpage
48 | \vbox to 2.5in{
49 | \vspace*{\fill}
50 | \vskip 2em
51 | \begin{center}%
52 | {\Large\bf \@title \par}%
53 | \vskip 0.375in minus 0.300in
54 | {\large\it
55 | \lineskip .5em
56 | \begin{tabular}[t]{c}\@author
57 | \end{tabular}\par}%
58 | \end{center}%
59 | \par
60 | \vspace*{\fill}
61 | % \vskip 1.5em
62 | }
63 | }
64 |
65 | %
66 | % The abstract is preceded by a 12-pt bold centered heading
67 | \def\abstract{\begin{center}%
68 | {\large\bf \abstractname\vspace{-.5em}\vspace{\z@}}%
69 | \end{center}}
70 | \def\endabstract{}
71 |
72 | %
73 | % Main section titles are 12-pt bold. Others can be same or smaller.
74 | %
75 | \def\section{\@startsection {section}{1}{\z@}{-3.5ex plus-1ex minus
76 | -.2ex}{2.3ex plus.2ex}{\reset@font\large\bf}}
77 |
--------------------------------------------------------------------------------
/figures/three-bells.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/figures/sender-trust.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/figures/recipient-trust.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/usenix.sty:
--------------------------------------------------------------------------------
1 | % usenix.sty - to be used with latex2e for USENIX.
2 | % To use this style file, look at the template usenix_template.tex
3 | %
4 | % $Id: usenix.sty,v 1.2 2005/02/16 22:30:47 maniatis Exp $
5 | %
6 | % The following definitions are modifications of standard article.sty
7 | % definitions, arranged to do a better job of matching the USENIX
8 | % guidelines.
9 | % It will automatically select two-column mode and the Times-Roman
10 | % font.
11 |
12 | %
13 | % USENIX papers are two-column.
14 | % Times-Roman font is nice if you can get it (requires NFSS,
15 | % which is in latex2e.
16 |
17 | \if@twocolumn\fi
18 | \usepackage{mathptmx} % times roman, including math (where possible)
19 |
20 | %
21 | % USENIX wants margins of: 1" sides, 1" bottom, and 1" top.
22 | % 0.25" gutter between columns.
23 | % Gives active areas of 6.5" x 9"
24 | %
25 | \setlength{\textheight}{9.0in}
26 | \setlength{\columnsep}{0.25in}
27 | \setlength{\textwidth}{6.50in}
28 |
29 | \setlength{\topmargin}{0.0in}
30 |
31 | \setlength{\headheight}{0.0in}
32 |
33 | \setlength{\headsep}{0.0in}
34 |
35 | % Usenix wants no page numbers for camera-ready papers, so that they can
36 | % number them themselves. But submitted papers should have page numbers
37 | % for the reviewers' convenience.
38 | %
39 | %
40 | % \pagestyle{empty}
41 |
42 | %
43 | % Usenix titles are in 14-point bold type, with no date, and with no
44 | % change in the empty page headers. The whole author section is 12 point
45 | % italic--- you must use {\rm } around the actual author names to get
46 | % them in roman.
47 | %
48 | \def\maketitle{\par
49 | \begingroup
50 | \renewcommand\thefootnote{\fnsymbol{footnote}}%
51 | \def\@makefnmark{\hbox to\z@{$\m@th^{\@thefnmark}$\hss}}%
52 | \long\def\@makefntext##1{\parindent 1em\noindent
53 | \hbox to1.8em{\hss$\m@th^{\@thefnmark}$}##1}%
54 | \if@twocolumn
55 | \twocolumn[\@maketitle]%
56 | \else \newpage
57 | \global\@topnum\z@
58 | \@maketitle \fi\@thanks
59 | \endgroup
60 | \setcounter{footnote}{0}%
61 | \let\maketitle\relax
62 | \let\@maketitle\relax
63 | \gdef\@thanks{}\gdef\@author{}\gdef\@title{}\let\thanks\relax}
64 |
65 | \def\@maketitle{\newpage
66 | \vbox to 2.5in{
67 | \vspace*{\fill}
68 | \vskip 2em
69 | \begin{center}%
70 | {\Large\bf \@title \par}%
71 | \vskip 0.375in minus 0.300in
72 | {\large\it
73 | \lineskip .5em
74 | \begin{tabular}[t]{c}\@author
75 | \end{tabular}\par}%
76 | \end{center}%
77 | \par
78 | \vspace*{\fill}
79 | % \vskip 1.5em
80 | }
81 | }
82 |
83 | %
84 | % The abstract is preceded by a 12-pt bold centered heading
85 | \def\abstract{\begin{center}%
86 | {\large\bf \abstractname\vspace{-.5em}\vspace{\z@}}%
87 | \end{center}}
88 | \def\endabstract{}
89 |
90 | %
91 | % Main section titles are 12-pt bold. Others can be same or smaller.
92 | %
93 | \def\section{\@startsection {section}{1}{\z@}{-3.5ex plus-1ex minus
94 | -.2ex}{2.3ex plus.2ex}{\reset@font\large\bf}}
95 |
96 | %
97 | % Shortcut for typesetting tuples
98 | %
99 | \newcommand{\tuple}[1]{\langle #1 \rangle}
--------------------------------------------------------------------------------
/figures/settlement-trust.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/figures/connector.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/interledger.bib:
--------------------------------------------------------------------------------
1 | @article{Bitcoin,
2 | abstract = {A purely peer-to-peer version of electronic cash would allow online
3 | payments to be sent directly from one party to another without going through a
4 | financial institution. Digital signatures provide part of the solution, but the main benefits are lost if a trusted third party is still required to prevent double-spending.
5 | We propose a solution to the double-spending problem using a peer-to-peer network. The network timestamps transactions by hashing them into an ongoing chain of hash-based proof-of-work, forming a record that cannot be changed without redoing the proof-of-work. The longest chain not only serves as proof of the sequence of events witnessed, but proof that it came from the largest pool of {CPU} power. As long as a majority of {CPU} power is controlled by nodes that are not cooperating to attack the network, they'll generate the longest chain and outpace attackers. The network itself requires minimal structure. Messages are broadcast on a best effort
6 | basis, and nodes can leave and rejoin the network at will, accepting the longest proof-of-work chain as proof of what happened while they were gone.},
7 | author = {Nakamoto, Satoshi},
8 | keywords = {bitcoin, cryptographic\_protocols, cryptography, electronic\_cash\_system, electronic\_commerce, hashcash, peer\_to\_peer\_network, proof\_of\_work},
9 | posted-at = {2011-01-01 14:24:54},
10 | priority = {0},
11 | title = {Bitcoin: A {Peer-to-Peer} Electronic Cash System},
12 | url = {http:bitcoin.org/bitcoin.pdf}
13 | }
14 | @article{1_mohan_lindsay_1985,
15 | author={Mohan, C. and Lindsay, B.},
16 | title={Efficient Commit Protocols for the Tree of Processes Model of Distributed Transactions},
17 | volume={19},
18 | url={http://doi.acm.org/10.1145/850770.850772},
19 | number={2},
20 | journal={SIGOPS Oper. Syst. Rev.},
21 | year={1985},
22 | pages={40--52}
23 | },
24 |
25 | @article{2_reed_1983,
26 | author={Reed, David P.},
27 | title={Implementing Atomic Actions on Decentralized Data},
28 | volume={1},
29 | url={http://doi.acm.org/10.1145/357353.357355},
30 | number={1},
31 | journal={ACM Trans. Comput. Syst.},
32 | year={1983},
33 | pages={3--23}
34 | }
35 | @inproceedings{Gray:1978:NDB:647433.723863,
36 | author = {Gray, Jim},
37 | title = {Notes on Data Base Operating Systems},
38 | booktitle = {Operating Systems, An Advanced Course},
39 | year = {1978},
40 | isbn = {3-540-08755-9},
41 | pages = {393--481},
42 | numpages = {89},
43 | url = {http://dl.acm.org/citation.cfm?id=647433.723863},
44 | acmid = {723863},
45 | publisher = {Springer-Verlag},
46 | address = {London, UK, UK},
47 | }
48 |
49 | @inproceedings{chaum1990untraceable,
50 | title={Untraceable electronic cash},
51 | author={Chaum, David and Fiat, Amos and Naor, Moni},
52 | booktitle={Proceedings on Advances in cryptology},
53 | pages={319--327},
54 | year={1990},
55 | organization={Springer-Verlag New York, Inc.}
56 | }
57 |
58 | @inproceedings{rompel1990one,
59 | title={One-way functions are necessary and sufficient for secure signatures},
60 | author={Rompel, John},
61 | booktitle={Proceedings of the twenty-second annual ACM symposium on Theory of computing},
62 | pages={387--394},
63 | year={1990},
64 | organization={ACM}
65 | }
66 |
67 | @article{black1973pricing,
68 | title={The pricing of options and corporate liabilities},
69 | author={Black, Fischer and Scholes, Myron},
70 | journal={The journal of political economy},
71 | pages={637--654},
72 | year={1973},
73 | publisher={JSTOR}
74 | }
75 |
76 | @inproceedings{castro1999practical,
77 | title={Practical Byzantine fault tolerance},
78 | author={Castro, Miguel and Liskov, Barbara and others},
79 | booktitle={OSDI},
80 | volume={99},
81 | pages={173--186},
82 | year={1999}
83 | }
84 |
85 | @article{back2014enabling,
86 | title={Enabling blockchain innovations with pegged sidechains},
87 | author={Back, Adam and Corallo, Matt and Dashjr, Luke and Friedenbach, Mark and Maxwell, Gregory and Miller, Andrew and Poelstra, Andrew and Tim{\'o}n, Jorge and Wuille, Pieter},
88 | journal={URL: http://www. opensciencereview. com/papers/123/enablingblockchain-innovations-with-pegged-sidechains},
89 | year={2014}
90 | }
91 |
92 | @article{alpern1985defining,
93 | title={Defining liveness},
94 | author={Alpern, Bowen and Schneider, Fred B},
95 | journal={Information processing letters},
96 | volume={21},
97 | number={4},
98 | pages={181--185},
99 | year={1985},
100 | publisher={Elsevier}
101 | }
102 |
103 | @article{brennan1977valuation,
104 | title={The valuation of American put options},
105 | author={Brennan, Michael J and Schwartz, Eduardo S},
106 | journal={Journal of Finance},
107 | pages={449--462},
108 | year={1977},
109 | publisher={JSTOR}
110 | }
111 |
112 | @article{gray2006consensus,
113 | title={Consensus on transaction commit},
114 | author={Gray, Jim and Lamport, Leslie},
115 | journal={ACM Transactions on Database Systems (TODS)},
116 | volume={31},
117 | number={1},
118 | pages={133--160},
119 | year={2006},
120 | publisher={ACM}
121 | }
122 |
123 | @article{copelandtangaroa,
124 | title={Tangaroa: a Byzantine Fault Tolerant Raft},
125 | author={Copeland, Christopher and Zhong, Hongxia}
126 | }
127 |
128 | @article{dwork1988consensus,
129 | title={Consensus in the presence of partial synchrony},
130 | author={Dwork, Cynthia and Lynch, Nancy and Stockmeyer, Larry},
131 | journal={Journal of the ACM (JACM)},
132 | volume={35},
133 | number={2},
134 | pages={288--323},
135 | year={1988},
136 | publisher={ACM}
137 | }
138 |
139 | @inproceedings{mohan1983method,
140 | title={Method for distributed transaction commit and recovery using Byzantine agreement within clusters of processors},
141 | author={Mohan, C and Strong, R and Finkelstein, Shel},
142 | booktitle={Proceedings of the second annual ACM symposium on Principles of distributed computing},
143 | pages={89--103},
144 | year={1983},
145 | organization={ACM}
146 | }
147 |
148 | @techreport{ahuja1988network,
149 | title={Network flows},
150 | author={Ahuja, Ravindra K and Magnanti, Thomas L and Orlin, James B},
151 | year={1988},
152 | institution={DTIC Document},
153 | pages={97--152}
154 | }
155 |
156 | @article{wagner1959class,
157 | title={On a class of capacitated transportation problems},
158 | author={Wagner, Harvey M},
159 | journal={Management Science},
160 | volume={5},
161 | number={3},
162 | pages={304--318},
163 | year={1959},
164 | publisher={INFORMS}
165 | }
166 |
167 | @article{cai2001time,
168 | title={Time-varying minimum cost flow problems},
169 | author={Cai, X and Sha, D and Wong, CK},
170 | journal={European Journal of Operational Research},
171 | volume={131},
172 | number={2},
173 | pages={352--374},
174 | year={2001},
175 | publisher={Elsevier}
176 | }
177 |
178 | @article{dolev1983authenticated,
179 | title={Authenticated algorithms for Byzantine agreement},
180 | author={Dolev, Danny and Strong, H. Raymond},
181 | journal={SIAM Journal on Computing},
182 | volume={12},
183 | number={4},
184 | pages={656--666},
185 | year={1983},
186 | publisher={SIAM}
187 | }
188 |
189 | @article{schwartz2014ripple,
190 | title={The Ripple protocol consensus algorithm},
191 | author={Schwartz, David and Youngs, Noah and Britto, Arthur},
192 | journal={Ripple Labs Inc White Paper},
193 | year={2014}
194 | }
195 |
196 | @article{mazieresstellar,
197 | title={The Stellar Consensus Protocol: A Federated Model for Internet-level Consensus},
198 | author={Mazi{\`e}res, David}
199 | }
200 |
201 | @article{poonbitcoin,
202 | title={The Bitcoin Lightning Network},
203 | author={Poon, Joseph and Dryja, Thaddeus}
204 | }
205 |
206 | @misc{wood2014ethereum,
207 | title={ETHEREUM: A SECURE DECENTRALISED GENERALISED TRANSACTION LEDGER},
208 | author={WOOD, DR GAVIN},
209 | year={2014},
210 | publisher={Ethereum}
211 | }
212 |
213 | @book{davies1989security,
214 | title={Security for computer networks: and introduction to data security in teleprocessing and electronic funds transfer},
215 | author={Davies, Donald Watts and Price, Wyn L},
216 | year={1989},
217 | publisher={John Wiley \& Sons, Inc.}
218 | }
219 |
220 | @inproceedings{aiyer2005bar,
221 | title={BAR fault tolerance for cooperative services},
222 | author={Aiyer, Amitanand S and Alvisi, Lorenzo and Clement, Allen and Dahlin, Mike and Martin, Jean-Philippe and Porth, Carl},
223 | booktitle={ACM SIGOPS Operating Systems Review},
224 | volume={39},
225 | number={5},
226 | pages={45--58},
227 | year={2005},
228 | organization={ACM}
229 | }
230 |
231 | @article{lamport1982byzantine,
232 | title={The Byzantine generals problem},
233 | author={Lamport, Leslie and Shostak, Robert and Pease, Marshall},
234 | journal={ACM Transactions on Programming Languages and Systems (TOPLAS)},
235 | volume={4},
236 | number={3},
237 | pages={382--401},
238 | year={1982},
239 | publisher={ACM}
240 | }
241 |
242 | @article{watts1998collective,
243 | title={Collective dynamics of ‘small-world’networks},
244 | author={Watts, Duncan J and Strogatz, Steven H},
245 | journal={nature},
246 | volume={393},
247 | number={6684},
248 | pages={440--442},
249 | year={1998},
250 | publisher={Nature Publishing Group}
251 | }
252 |
253 | @article{albert1999internet,
254 | title={Internet: Diameter of the world-wide web},
255 | author={Albert, R{\'e}ka and Jeong, Hawoong and Barab{\'a}si, Albert-L{\'a}szl{\'o}},
256 | journal={Nature},
257 | volume={401},
258 | number={6749},
259 | pages={130--131},
260 | year={1999},
261 | publisher={Nature Publishing Group}
262 | }
263 |
264 | @article{bracha1985asynchronous,
265 | title={Asynchronous consensus and broadcast protocols},
266 | author={Bracha, Gabriel and Toueg, Sam},
267 | journal={Journal of the ACM (JACM)},
268 | volume={32},
269 | number={4},
270 | pages={824--840},
271 | year={1985},
272 | publisher={ACM}
273 | }
--------------------------------------------------------------------------------
/figures/payment-chain.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/tla/Atomic.tla:
--------------------------------------------------------------------------------
1 | ------------------------------- MODULE Atomic -------------------------------
2 | (***************************************************************************)
3 | (* Formal Specification in TLA^+ of the *)
4 | (* Interledger Protocol Atomic (ILP/A) *)
5 | (* *)
6 | (*`. *)
7 | (* Modeled after the excellent Raft specification by Diego Ongaro. *)
8 | (* Available at https://github.com/ongardie/raft.tla *)
9 | (* *)
10 | (* Copyright 2014 Diego Ongaro. *)
11 | (* This work is licensed under the Creative Commons Attribution-4.0 *)
12 | (* International License https://creativecommons.org/licenses/by/4.0/ .'*)
13 | (***************************************************************************)
14 |
15 | EXTENDS Naturals, Sequences, Bags, TLC
16 |
17 | \* The set of ledger IDs
18 | CONSTANTS Ledger
19 |
20 | \* The set of participant IDs
21 | CONSTANTS Participant
22 |
23 | \* The notary
24 | CONSTANTS Notary
25 |
26 | \* Sender states
27 | CONSTANTS S_Ready, S_Waiting, S_Done
28 |
29 | \* Notary states
30 | CONSTANTS N_Waiting, N_Committed, N_Aborted
31 |
32 | \* Notary decisions
33 | CONSTANTS D_Execute, D_Abort
34 |
35 | \* Ledger states
36 | CONSTANTS L_Proposed, L_Prepared, L_Executed, L_Aborted
37 |
38 | \* Message types
39 | CONSTANTS M_PrepareRequest, M_ExecuteRequest, M_AbortRequest,
40 | M_PrepareNotify, M_ExecuteNotify, M_AbortNotify,
41 | M_SubmitReceiptRequest
42 |
43 | \* Receipt signature
44 | CONSTANTS R_ReceiptSignature
45 |
46 | ----
47 | \* Global variables
48 |
49 | \* A bag of records representing requests and responses sent from one process
50 | \* to another
51 | VARIABLE messages
52 |
53 | ----
54 | \* Sender variables
55 |
56 | \* State of the sender (S_Ready, S_Waiting, S_Done)
57 | VARIABLE senderState
58 |
59 | \* All sender variables
60 | senderVars == <>
61 | ----
62 | \* The following variables are all per ledger (functions with domain Ledger)
63 |
64 | \* The ledger state (L_Proposed, L_Prepared, L_Executed or L_Aborted)
65 | VARIABLE ledgerState
66 |
67 | \* All ledger variables
68 | ledgerVars == <>
69 | ----
70 | \* Notary variables
71 |
72 | \* State of the notary (N_Waiting, N_Committed, N_Aborted)
73 | VARIABLE notaryState
74 |
75 | \* All notary variables
76 | notaryVars == <>
77 | ----
78 |
79 | \* All variables; used for stuttering (asserting state hasn't changed)
80 | vars == <>
81 |
82 | ----
83 | \* Helpers
84 |
85 | \* Add a set of new messages in transit
86 | Broadcast(m) == messages' = messages (+) SetToBag(m)
87 |
88 | \* Add a message to the bag of messages
89 | Send(m) == Broadcast({m})
90 |
91 | \* Remove a message from the bag of messages. Used when a process is done
92 | \* processing a message.
93 | Discard(m) == messages' = messages (-) SetToBag({m})
94 |
95 | \* Respond to a message by sending multiple messages
96 | ReplyBroadcast(responses, request) ==
97 | messages' = messages (-) SetToBag({request}) (+) SetToBag(responses)
98 |
99 | \* Combination of Send and Discard
100 | Reply(response, request) ==
101 | ReplyBroadcast({response}, request)
102 |
103 |
104 | \* Return the minimum value from a set, or undefined if the set is empty.
105 | Min(s) == CHOOSE x \in s : \A y \in s : x <= y
106 | \* Return the maximum value from a set, or undefined if the set is empty.
107 | Max(s) == CHOOSE x \in s : \A y \in s : x >= y
108 |
109 | \* Is a final ledger state
110 | IsFinalLedgerState(i) == i \in {L_Executed, L_Aborted}
111 |
112 | \* Sender
113 | Sender == Min(Participant)
114 |
115 | \* Recipient
116 | Recipient == Max(Participant)
117 |
118 | \* Set of connectors
119 | Connector == Participant \ {Sender, Recipient}
120 |
121 | ----
122 | \* Define type specification for all variables
123 |
124 | TypeOK == /\ IsABag(messages)
125 | /\ senderState \in {S_Ready, S_Waiting, S_Done}
126 | /\ ledgerState \in [Ledger -> {L_Proposed, L_Prepared, L_Executed, L_Aborted}]
127 |
128 | Consistency ==
129 | \A l1, l2 \in Ledger : \lnot /\ ledgerState[l1] = L_Aborted
130 | /\ ledgerState[l2] = L_Executed
131 |
132 | Inv == /\ TypeOK
133 | /\ Consistency
134 |
135 | ----
136 | \* Define initial values for all variables
137 |
138 | InitSenderVars == /\ senderState = S_Ready
139 |
140 | InitLedgerVars == /\ ledgerState = [i \in Ledger |-> L_Proposed]
141 |
142 | InitNotaryVars == /\ notaryState = N_Waiting
143 |
144 | Init == /\ messages = EmptyBag
145 | /\ InitSenderVars
146 | /\ InitLedgerVars
147 | /\ InitNotaryVars
148 |
149 | ----
150 | \* Define state transitions
151 |
152 | \* Participant i starts off the chain
153 | Start(i) ==
154 | /\ senderState = S_Ready
155 | /\ senderState' = S_Waiting
156 | /\ Send([mtype |-> M_PrepareRequest,
157 | msource |-> i,
158 | mdest |-> i+1])
159 | /\ UNCHANGED <>
160 |
161 | \* Notary times out
162 | NotaryTimeout ==
163 | /\ notaryState = N_Waiting
164 | /\ notaryState' = N_Aborted
165 | /\ Broadcast(
166 | {[mtype |-> M_AbortRequest,
167 | msource |-> Notary,
168 | mdest |-> k,
169 | msig |-> D_Abort] : k \in Ledger})
170 | /\ UNCHANGED <>
171 |
172 | \* Ledger spontaneously aborts
173 | LedgerAbort(l) ==
174 | /\ ledgerState[l] = L_Proposed
175 | /\ ledgerState' = [ledgerState EXCEPT ![l] = L_Aborted]
176 | /\ Send([mtype |-> M_AbortNotify,
177 | msource |-> l,
178 | mdest |-> l-1])
179 | /\ UNCHANGED <>
180 |
181 | ----
182 | \* Message handlers
183 | \* i = recipient, j = sender, m = message
184 |
185 | \* Ledger i receives a Prepare request from process j
186 | LedgerHandlePrepareRequest(i, j, m) ==
187 | LET valid == /\ ledgerState[i] = L_Proposed
188 | /\ j = i - 1
189 | IN \/ /\ valid
190 | /\ ledgerState' = [ledgerState EXCEPT ![i] = L_Prepared]
191 | /\ Reply([mtype |-> M_PrepareNotify,
192 | msource |-> i,
193 | mdest |-> i+1], m)
194 | /\ UNCHANGED <>
195 | \/ /\ \lnot valid
196 | /\ Discard(m)
197 | /\ UNCHANGED <>
198 |
199 | \* Ledger i receives an Execute request from process j
200 | LedgerHandleExecuteRequest(i, j, m) ==
201 | LET valid == /\ ledgerState[i] = L_Prepared
202 | /\ m.msig = D_Execute
203 | IN \/ /\ valid
204 | /\ ledgerState' = [ledgerState EXCEPT ![i] = L_Executed]
205 | /\ Reply([mtype |-> M_ExecuteNotify,
206 | msource |-> i,
207 | mdest |-> i-1], m)
208 | /\ UNCHANGED <>
209 | \/ /\ \lnot valid
210 | /\ Discard(m)
211 | /\ UNCHANGED <>
212 |
213 | \* Ledger i receives an Abort request from process j
214 | LedgerHandleAbortRequest(i, j, m) ==
215 | LET valid == /\ ledgerState[i] \in { L_Proposed, L_Prepared }
216 | /\ m.msig = D_Abort
217 | IN \/ /\ valid
218 | /\ ledgerState' = [ledgerState EXCEPT ![i] = L_Aborted]
219 | /\ Reply([mtype |-> M_AbortNotify,
220 | msource |-> i,
221 | mdest |-> i-1], m)
222 | /\ UNCHANGED <>
223 | \/ /\ \lnot valid
224 | /\ Discard(m)
225 | /\ UNCHANGED <>
226 |
227 | \* Ledger i receives a message
228 | LedgerReceive(i, j, m) ==
229 | \/ /\ m.mtype = M_PrepareRequest
230 | /\ LedgerHandlePrepareRequest(i, j, m)
231 | \/ /\ m.mtype = M_ExecuteRequest
232 | /\ LedgerHandleExecuteRequest(i, j, m)
233 | \/ /\ m.mtype = M_AbortRequest
234 | /\ LedgerHandleAbortRequest(i, j, m)
235 |
236 | \* Ledger j notifies sender that the transfer is executed
237 | SenderHandleExecuteNotify(i, j, m) ==
238 | \/ /\ senderState = S_Waiting
239 | /\ senderState' = S_Done
240 | /\ Discard(m)
241 | /\ UNCHANGED <>
242 | \/ /\ senderState # S_Waiting
243 | /\ Discard(m)
244 | /\ UNCHANGED <>
245 |
246 | \* Ledger j notifies sender that the transfer is aborted
247 | SenderHandleAbortNotify(i, j, m) ==
248 | LET isSenderWaiting == senderState \in { S_Waiting, S_Ready }
249 | IN \/ /\ isSenderWaiting
250 | /\ senderState' = S_Done
251 | /\ Discard(m)
252 | /\ UNCHANGED <>
253 | \/ /\ \lnot isSenderWaiting
254 | /\ Discard(m)
255 | /\ UNCHANGED <>
256 |
257 | \* Sender receives a message
258 | SenderReceive(i, j, m) ==
259 | \/ /\ m.mtype = M_ExecuteNotify
260 | /\ SenderHandleExecuteNotify(i, j, m)
261 | \/ /\ m.mtype = M_AbortNotify
262 | /\ SenderHandleAbortNotify(i, j, m)
263 |
264 | \* Ledger j notifies recipient that the transfer is prepared
265 | RecipientHandlePrepareNotify(i, j, m) ==
266 | /\ Reply([mtype |-> M_SubmitReceiptRequest,
267 | msource |-> i,
268 | mdest |-> Notary,
269 | mreceipt |-> R_ReceiptSignature], m)
270 | /\ UNCHANGED <>
271 |
272 | \* Recipient receives a message
273 | RecipientReceive(i, j, m) ==
274 | /\ m.mtype = M_PrepareNotify
275 | /\ RecipientHandlePrepareNotify(i, j, m)
276 |
277 | \* Ledger j notifies connector i that the transfer is prepared
278 | ConnectorHandlePrepareNotify(i, j, m) ==
279 | /\ Reply([mtype |-> M_PrepareRequest,
280 | msource |-> i,
281 | mdest |-> i+1], m)
282 | /\ UNCHANGED <>
283 |
284 | \* Ledger j notifies connector i that the transfer is executed
285 | ConnectorHandleExecuteNotify(i, j, m) ==
286 | /\ Discard(m)
287 | /\ UNCHANGED <>
288 |
289 | \* Ledger j notifies connector i that the transfer is aborted
290 | ConnectorHandleAbortNotify(i, j, m) ==
291 | /\ Discard(m)
292 | /\ UNCHANGED <>
293 |
294 | \* Connector receives a message
295 | ConnectorReceive(i, j, m) ==
296 | \/ /\ m.mtype = M_PrepareNotify
297 | /\ ConnectorHandlePrepareNotify(i, j, m)
298 | \/ /\ m.mtype = M_ExecuteNotify
299 | /\ ConnectorHandleExecuteNotify(i, j, m)
300 | \/ /\ m.mtype = M_AbortNotify
301 | /\ ConnectorHandleAbortNotify(i, j, m)
302 |
303 | \* Notary receives a signed receipt
304 | NotaryHandleSubmitReceiptRequest(i, j, m) ==
305 | \/ /\ m.mreceipt = R_ReceiptSignature
306 | /\ notaryState = N_Waiting
307 | /\ notaryState' = N_Committed
308 | /\ ReplyBroadcast(
309 | {[mtype |-> M_ExecuteRequest,
310 | msource |-> i,
311 | mdest |-> k,
312 | msig |-> D_Execute] : k \in Ledger}, m)
313 | /\ UNCHANGED <>
314 | \/ /\ notaryState # N_Waiting
315 | /\ Discard(m)
316 | /\ UNCHANGED <>
317 |
318 | \* Notary receives a message
319 | NotaryReceive(i, j, m) ==
320 | /\ m.mtype = M_SubmitReceiptRequest
321 | /\ NotaryHandleSubmitReceiptRequest(i, j, m)
322 |
323 | \* Receive a message
324 | Receive(m) ==
325 | LET i == m.mdest
326 | j == m.msource
327 | IN \/ /\ i \in Ledger
328 | /\ LedgerReceive(i, j, m)
329 | \/ /\ i = Sender
330 | /\ SenderReceive(i, j, m)
331 | \/ /\ i = Recipient
332 | /\ RecipientReceive(i, j, m)
333 | \/ /\ i \in Connector
334 | /\ ConnectorReceive(i, j, m)
335 | \/ /\ i = Notary
336 | /\ NotaryReceive(i, j, m)
337 |
338 | \* End of message handlers
339 | ----
340 | \* Defines how the variables may transition
341 |
342 | Termination ==
343 | /\ \A l \in Ledger : IsFinalLedgerState(ledgerState[l])
344 | /\ senderState = S_Done
345 | /\ UNCHANGED vars
346 |
347 | Next == \/ Start(Sender)
348 | \/ NotaryTimeout
349 | \/ \E l \in Ledger : LedgerAbort(l)
350 | \/ \E m \in DOMAIN messages : Receive(m)
351 | \/ Termination
352 |
353 | \* The specification must start with the initial state and transition according
354 | \* to Next.
355 | Spec == Init /\ [][Next]_vars
356 |
357 | =============================================================================
358 |
--------------------------------------------------------------------------------
/tla/Universal.tla:
--------------------------------------------------------------------------------
1 | ------------------------------- MODULE Universal -------------------------------
2 | (***************************************************************************)
3 | (* Formal Specification in TLA^+ of the *)
4 | (* Interledger Protocol Universal (ILP/U) *)
5 | (* *)
6 | (*`. *)
7 | (* Modeled after the excellent Raft specification by Diego Ongaro. *)
8 | (* Available at https://github.com/ongardie/raft.tla *)
9 | (* *)
10 | (* Copyright 2014 Diego Ongaro. *)
11 | (* This work is licensed under the Creative Commons Attribution-4.0 *)
12 | (* International License https://creativecommons.org/licenses/by/4.0/ .'*)
13 | (***************************************************************************)
14 |
15 | EXTENDS Naturals, Sequences, FiniteSets, Bags, TLC
16 |
17 | \* The set of ledger IDs
18 | CONSTANTS Ledger
19 |
20 | \* The set of participant IDs
21 | CONSTANTS Participant
22 |
23 | \* Sender states
24 | CONSTANTS S_Ready, S_ProposalWaiting, S_Waiting, S_Done
25 |
26 | \* Connector states
27 | CONSTANTS C_Ready, C_Proposed
28 |
29 | \* Ledger states
30 | CONSTANTS L_Proposed, L_Prepared, L_Executed, L_Aborted
31 |
32 | \* Message types
33 | CONSTANTS PrepareRequest, ExecuteRequest, AbortRequest,
34 | PrepareNotify, ExecuteNotify, AbortNotify,
35 | SubpaymentProposalRequest, SubpaymentProposalResponse
36 |
37 | \* Receipt signature
38 | CONSTANTS R_ReceiptSignature
39 |
40 | ----
41 | \* Global variables
42 |
43 | \* Under synchrony we are allowed to have a global clock
44 | VARIABLE clock
45 |
46 | \* A bag of records representing requests and responses sent from one process
47 | \* to another
48 | VARIABLE messages
49 |
50 | ----
51 | \* Sender variables
52 |
53 | \* State of the sender (S_Ready, S_Waiting, S_Done)
54 | VARIABLE senderState
55 |
56 | \* Whether the sender has received a response from a given connector
57 | VARIABLE senderProposalResponses
58 |
59 | \* All sender variables
60 | senderVars == <>
61 | ----
62 | \* Connector variables
63 |
64 | \* State of the connector (C_Ready, C_Proposed)
65 | VARIABLE connectorState
66 |
67 | \* All sender variables
68 | connectorVars == <>
69 | ----
70 | \* The following variables are all per ledger (functions with domain Ledger)
71 |
72 | \* The ledger state (L_Proposed, L_Prepared, L_Executed or L_Aborted)
73 | VARIABLE ledgerState
74 |
75 | \* The timeouts for each of the the transfers
76 | VARIABLE ledgerExpiration
77 |
78 | \* All ledger variables
79 | ledgerVars == <>
80 | ----
81 |
82 | \* All variables; used for stuttering (asserting state hasn't changed)
83 | vars == <>
84 |
85 | ----
86 | \* Helpers
87 |
88 | \* Add a set of new messages in transit
89 | Broadcast(m) == messages' = messages (+) SetToBag(m)
90 |
91 | \* Add a message to the bag of messages
92 | Send(m) == Broadcast({m})
93 |
94 | \* Remove a message from the bag of messages. Used when a process is done
95 | \* processing a message.
96 | Discard(m) == messages' = messages (-) SetToBag({m})
97 |
98 | \* Respond to a message by sending multiple messages
99 | ReplyBroadcast(responses, request) ==
100 | messages' = messages (-) SetToBag({request}) (+) SetToBag(responses)
101 |
102 | \* Combination of Send and Discard
103 | Reply(response, request) ==
104 | ReplyBroadcast({response}, request)
105 |
106 |
107 | \* Return the minimum value from a set, or undefined if the set is empty.
108 | Min(s) == CHOOSE x \in s : \A y \in s : x <= y
109 | \* Return the maximum value from a set, or undefined if the set is empty.
110 | Max(s) == CHOOSE x \in s : \A y \in s : x >= y
111 |
112 | \* Is a final ledger state
113 | IsFinalLedgerState(i) == i \in {L_Executed, L_Aborted}
114 |
115 | \* Sender
116 | Sender == Min(Participant)
117 |
118 | \* Recipient
119 | Recipient == Max(Participant)
120 |
121 | \* Set of connectors
122 | Connector == Participant \ {Sender, Recipient}
123 |
124 | \* The clock value we expect to be at after the proposal phase
125 | ClockAfterProposal == 2 * Cardinality(Connector) + 2
126 |
127 | \* The clock value we expect after the preparation phase
128 | ClockAfterPrepare == ClockAfterProposal + 2 * Cardinality(Ledger) + 1
129 |
130 | \* The clock value we expect to be at after the execution phase
131 | ClockAfterExecution == ClockAfterPrepare + 2 * Cardinality(Ledger) + 1
132 | ----
133 | \* Define type specification for all variables
134 |
135 | TypeOK == /\ clock \in Nat
136 | /\ IsABag(messages)
137 | /\ senderState \in {S_Ready, S_ProposalWaiting, S_Waiting, S_Done}
138 | /\ senderProposalResponses \in [Connector -> BOOLEAN]
139 | /\ connectorState \in [Connector -> {C_Ready, C_Proposed}]
140 | /\ ledgerState \in [Ledger -> {L_Proposed, L_Prepared, L_Executed, L_Aborted}]
141 | /\ ledgerExpiration \in [Ledger -> Nat]
142 |
143 | Consistency ==
144 | \A l1, l2 \in Ledger : \lnot /\ ledgerState[l1] = L_Aborted
145 | /\ ledgerState[l2] = L_Executed
146 |
147 | Inv == /\ TypeOK
148 | /\ Consistency
149 |
150 | ----
151 | \* Define initial values for all variables
152 |
153 | InitSenderVars == /\ senderState = S_Ready
154 | /\ senderProposalResponses = [i \in Connector |-> FALSE]
155 |
156 | InitConnectorVars == connectorState = [i \in Connector |-> C_Ready]
157 |
158 | InitLedgerVars == /\ ledgerState = [i \in Ledger |-> L_Proposed]
159 | /\ ledgerExpiration = [i \in Ledger |-> ClockAfterExecution - i]
160 |
161 | Init == /\ clock = 0
162 | /\ messages = EmptyBag
163 | /\ InitSenderVars
164 | /\ InitConnectorVars
165 | /\ InitLedgerVars
166 |
167 | ----
168 | \* Define state transitions
169 |
170 | \* Participant i proposes all the subpayments
171 | StartProposalPhase(i) ==
172 | /\ senderState = S_Ready
173 | /\ senderState' = S_ProposalWaiting
174 | /\ Broadcast({[
175 | mtype |-> SubpaymentProposalRequest,
176 | msource |-> i,
177 | mdest |-> k
178 | ] : k \in Connector})
179 | /\ UNCHANGED <>
180 |
181 | \* Participant i starts off the preparation chain
182 | StartPreparationPhase(i) ==
183 | /\ senderState = S_ProposalWaiting
184 | /\ \E p \in DOMAIN senderProposalResponses : senderProposalResponses[p]
185 | /\ senderState' = S_Waiting
186 | /\ Send([mtype |-> PrepareRequest,
187 | msource |-> i,
188 | mdest |-> i+1])
189 | /\ UNCHANGED <>
190 |
191 | \* Ledger spontaneously aborts
192 | LedgerAbort(l) ==
193 | /\ ledgerState[l] = L_Proposed
194 | /\ ledgerState' = [ledgerState EXCEPT ![l] = L_Aborted]
195 | /\ Send([mtype |-> AbortNotify,
196 | msource |-> l,
197 | mdest |-> l-1])
198 | /\ UNCHANGED <>
199 |
200 | \* Transfer times out
201 | LedgerTimeout(l) ==
202 | /\ \lnot IsFinalLedgerState(ledgerState[l])
203 | /\ ledgerExpiration[l] =< clock
204 | /\ ledgerState' = [ledgerState EXCEPT ![l] = L_Aborted]
205 | /\ Send([mtype |-> AbortNotify,
206 | msource |-> l,
207 | mdest |-> l-1])
208 | /\ UNCHANGED <>
209 |
210 | \* If no messages are in flight and the sender isn't doing anything, advance the
211 | \* clock
212 | NothingHappens ==
213 | /\ clock \leq Max({ledgerExpiration[x] : x \in Ledger})
214 | /\ BagCardinality(messages) = 0
215 | /\ senderState # S_Ready
216 | /\ \/ senderState # S_ProposalWaiting
217 | \/ \A p \in DOMAIN senderProposalResponses : \lnot senderProposalResponses[p]
218 | /\ UNCHANGED <>
219 |
220 | ----
221 | \* Message handlers
222 | \* i = recipient, j = sender, m = message
223 |
224 | \* Ledger i receives a Prepare request from participant j
225 | LedgerHandlePrepareRequest(i, j, m) ==
226 | LET valid == /\ ledgerState[i] = L_Proposed
227 | /\ j = i - 1
228 | IN \/ /\ valid
229 | /\ i \in Ledger
230 | /\ ledgerState' = [ledgerState EXCEPT ![i] = L_Prepared]
231 | /\ Reply([mtype |-> PrepareNotify,
232 | msource |-> i,
233 | mdest |-> i+1], m)
234 | /\ UNCHANGED <>
235 | \/ /\ \lnot valid
236 | /\ i \in Ledger
237 | /\ Discard(m)
238 | /\ UNCHANGED <>
239 |
240 | \* Ledger i receives an Execute request from process j
241 | LedgerHandleExecuteRequest(i, j, m) ==
242 | LET valid == /\ ledgerState[i] = L_Prepared
243 | /\ ledgerExpiration[i] > clock
244 | /\ m.mreceipt = R_ReceiptSignature
245 | IN \/ /\ valid
246 | /\ ledgerState' = [ledgerState EXCEPT ![i] = L_Executed]
247 | /\ Reply([mtype |-> ExecuteNotify,
248 | msource |-> i,
249 | mdest |-> i-1,
250 | mreceipt |-> m.mreceipt], m)
251 | /\ UNCHANGED <>
252 | \/ /\ \lnot valid
253 | /\ Discard(m)
254 | /\ UNCHANGED <>
255 |
256 | \* Ledger i receives a message
257 | LedgerReceive(i, j, m) ==
258 | \/ /\ m.mtype = PrepareRequest
259 | /\ LedgerHandlePrepareRequest(i, j, m)
260 | \/ /\ m.mtype = ExecuteRequest
261 | /\ LedgerHandleExecuteRequest(i, j, m)
262 |
263 | \* Sender receives a SubpaymentProposal request
264 | SenderHandleSubpaymentProposalResponse(i, j, m) ==
265 | /\ i = Sender
266 | /\ senderProposalResponses' = [senderProposalResponses EXCEPT ![j] = TRUE]
267 | /\ Discard(m)
268 | /\ UNCHANGED <>
269 |
270 | \* Ledger j notifies sender that the transfer is executed
271 | SenderHandleExecuteNotify(i, j, m) ==
272 | \/ /\ senderState = S_Waiting
273 | /\ senderState' = S_Done
274 | /\ Discard(m)
275 | /\ UNCHANGED <>
276 | \/ /\ senderState # S_Waiting
277 | /\ Discard(m)
278 | /\ UNCHANGED <>
279 |
280 | \* Ledger j notifies sender that the transfer is aborted
281 | SenderHandleAbortNotify(i, j, m) ==
282 | LET isSenderWaiting == senderState \in { S_ProposalWaiting, S_Waiting, S_Ready }
283 | IN \/ /\ isSenderWaiting
284 | /\ senderState' = S_Done
285 | /\ Discard(m)
286 | /\ UNCHANGED <>
287 | \/ /\ \lnot isSenderWaiting
288 | /\ Discard(m)
289 | /\ UNCHANGED <>
290 |
291 | \* Sender receives a message
292 | SenderReceive(i, j, m) ==
293 | \/ /\ m.mtype = SubpaymentProposalResponse
294 | /\ SenderHandleSubpaymentProposalResponse(i, j, m)
295 | \/ /\ m.mtype = ExecuteNotify
296 | /\ SenderHandleExecuteNotify(i, j, m)
297 | \/ /\ m.mtype = AbortNotify
298 | /\ SenderHandleAbortNotify(i, j, m)
299 |
300 | \* Ledger j notifies recipient that the transfer is prepared
301 | RecipientHandlePrepareNotify(i, j, m) ==
302 | \/ /\ Reply([mtype |-> ExecuteRequest,
303 | msource |-> i,
304 | mdest |-> i-1,
305 | mreceipt |-> R_ReceiptSignature], m)
306 | /\ UNCHANGED <>
307 |
308 | \* Recipient receives a message
309 | RecipientReceive(i, j, m) ==
310 | \/ /\ m.mtype = PrepareNotify
311 | /\ RecipientHandlePrepareNotify(i, j, m)
312 |
313 | \* Connector i receives a SubpaymentProposal request
314 | ConnectorHandleSubpaymentProposalRequest(i, j, m) ==
315 | /\ connectorState' = [connectorState EXCEPT ![i] = C_Proposed]
316 | /\ Reply([mtype |-> SubpaymentProposalResponse,
317 | msource |-> i,
318 | mdest |-> j], m)
319 | /\ UNCHANGED <>
320 |
321 | \* Ledger j notifies connector i that the transfer is prepared
322 | ConnectorHandlePrepareNotify(i, j, m) ==
323 | \/ /\ Reply([mtype |-> PrepareRequest,
324 | msource |-> i,
325 | mdest |-> i+1], m)
326 | /\ UNCHANGED <>
327 |
328 | \* Ledger j notifies connector i that the transfer is executed
329 | ConnectorHandleExecuteNotify(i, j, m) ==
330 | /\ Reply([mtype |-> ExecuteRequest,
331 | msource |-> i,
332 | mdest |-> i-1,
333 | mreceipt |-> m.mreceipt], m)
334 | /\ UNCHANGED <>
335 |
336 | \* Ledger j notifies connector i that the transfer is aborted
337 | ConnectorHandleAbortNotify(i, j, m) ==
338 | /\ Discard(m)
339 | /\ UNCHANGED <>
340 |
341 | \* Connector receives a message
342 | ConnectorReceive(i, j, m) ==
343 | \/ /\ m.mtype = SubpaymentProposalRequest
344 | /\ ConnectorHandleSubpaymentProposalRequest(i, j, m)
345 | \/ /\ m.mtype = PrepareNotify
346 | /\ ConnectorHandlePrepareNotify(i, j, m)
347 | \/ /\ m.mtype = ExecuteNotify
348 | /\ ConnectorHandleExecuteNotify(i, j, m)
349 | \/ /\ m.mtype = AbortNotify
350 | /\ ConnectorHandleAbortNotify(i, j, m)
351 |
352 | \* Receive a message
353 | Receive(m) ==
354 | LET i == m.mdest
355 | j == m.msource
356 | IN \/ /\ i \in Ledger
357 | /\ LedgerReceive(i, j, m)
358 | \/ /\ i = Sender
359 | /\ SenderReceive(i, j, m)
360 | \/ /\ i = Recipient
361 | /\ RecipientReceive(i, j, m)
362 | \/ /\ i \in Connector
363 | /\ ConnectorReceive(i, j, m)
364 |
365 | \* End of message handlers
366 | ----
367 | \* Defines how the variables may transition
368 |
369 | Termination ==
370 | /\ \A l \in Ledger : IsFinalLedgerState(ledgerState[l])
371 | /\ senderState = S_Done
372 | /\ UNCHANGED vars
373 |
374 | Next == \/ /\ \/ StartProposalPhase(Sender)
375 | \/ StartPreparationPhase(Sender)
376 | \/ \E l \in Ledger : LedgerAbort(l)
377 | \/ \E l \in Ledger : LedgerTimeout(l)
378 | \/ \E m \in DOMAIN messages : Receive(m)
379 | \/ NothingHappens
380 | /\ clock' = clock + 1
381 | \/ Termination
382 |
383 | \* The specification must start with the initial state and transition according
384 | \* to Next.
385 | Spec == Init /\ [][Next]_vars
386 |
387 | =============================================================================
388 |
--------------------------------------------------------------------------------
/figures/web-of-ledgers.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/specs/atomic.tex:
--------------------------------------------------------------------------------
1 | \batchmode %% Suppresses most terminal output.
2 | \documentclass[letterpaper,twocolumn,10pt]{article}
3 | \usepackage{color}
4 | \usepackage{ilpspec}
5 | % \usepackage{usenix}
6 | \definecolor{boxshade}{gray}{0.95}
7 |
8 | \setlength{\headheight}{0.0in}
9 |
10 | \usepackage{latexsym}
11 | \usepackage{ifthen}
12 | % \usepackage{color}
13 | \usepackage{tlatex}
14 |
15 | \begin{document}
16 | \onecolumn
17 | \appendix
18 | \stepcounter{section}
19 | \stepcounter{subsection}
20 | \stepcounter{subsection}
21 | \setcounter{page}{12}
22 | \subsection{Formal Specification: Atomic mode}
23 | \label{sec:atomic-spec}
24 | \tlatex
25 | \setboolean{shading}{true}
26 | \@x{}\moduleLeftDash\@xx{ {\MODULE} Atomic}\moduleRightDash\@xx{}%
27 | \begin{lcom}{0}%
28 | \begin{cpar}{0}{T}{F}{2.5}{0}{}%
29 | Formal Specification in TLA\ensuremath{\.{\mbox{}^+}} of the
30 | Interledger Protocol \ensuremath{Atomic} (\ensuremath{ILP}/A)
31 | \end{cpar}%
32 | \vshade{10.0}%
33 | \begin{cpar}{1}{F}{F}{0}{0}{}%
34 | \begin{minipage}[t]{\linewidth}
35 | \begin{verbatim}
36 | Modeled after the excellent Raft specification by Diego Ongaro.
37 | Available at https://github.com/ongardie/raft.tla
38 | \end{verbatim}
39 | \end{minipage}
40 | \end{cpar}%
41 | \vshade{5.0}%
42 | \begin{cpar}{0}{F}{F}{0}{0}{}%
43 | \begin{minipage}[t]{\linewidth}
44 | \begin{verbatim}
45 | Copyright 2014 Diego Ongaro.
46 | This work is licensed under the Creative Commons Attribution-4.0
47 | International License https://creativecommons.org/licenses/by/4.0/
48 | \end{verbatim}
49 | \end{minipage}
50 | \end{cpar}%
51 | \end{lcom}%
52 | \@pvspace{8.0pt}%
53 | \@x{ {\EXTENDS} Naturals ,\, Sequences ,\, Bags ,\, TLC}%
54 | \@pvspace{8.0pt}%
55 | \@x{}%
56 | \@y{\@s{0}%
57 | The set of ledger \ensuremath{IDs
58 | }}%
59 | \@xx{}%
60 | \@x{ {\CONSTANTS} Ledger}%
61 | \@pvspace{8.0pt}%
62 | \@x{}%
63 | \@y{\@s{0}%
64 | The set of participant \ensuremath{IDs
65 | }}%
66 | \@xx{}%
67 | \@x{ {\CONSTANTS} Participant}%
68 | \@pvspace{8.0pt}%
69 | \@x{}%
70 | \@y{\@s{0}%
71 | The notary
72 | }%
73 | \@xx{}%
74 | \@x{ {\CONSTANTS} Notary}%
75 | \@pvspace{8.0pt}%
76 | \@x{}%
77 | \@y{\@s{0}%
78 | Sender states
79 | }%
80 | \@xx{}%
81 | \@x{ {\CONSTANTS} S\_Ready ,\, S\_Waiting ,\, S\_Done}%
82 | \@pvspace{8.0pt}%
83 | \@x{}%
84 | \@y{\@s{0}%
85 | Notary states
86 | }%
87 | \@xx{}%
88 | \@x{ {\CONSTANTS} N\_Waiting ,\, N\_Committed ,\, N\_Aborted}%
89 | \@pvspace{8.0pt}%
90 | \@x{}%
91 | \@y{\@s{0}%
92 | Ledger states
93 | }%
94 | \@xx{}%
95 | \@x{ {\CONSTANTS} L\_Proposed ,\, L\_Prepared ,\, L\_Executed ,\, L\_Aborted}%
96 | \@pvspace{8.0pt}%
97 | \@x{}%
98 | \@y{\@s{0}%
99 | Message types
100 | }%
101 | \@xx{}%
102 | \@x{ {\CONSTANTS} PrepareRequest ,\, ExecuteRequest ,\, AbortRequest ,\,}%
103 | \@x{\@s{54.75} PrepareNotify ,\, ExecuteNotify ,\, AbortNotify ,\,}%
104 | \@x{\@s{54.75} SubmitReceiptRequest}%
105 | \@pvspace{8.0pt}%
106 | \@x{}%
107 | \@y{\@s{0}%
108 | Receipt signature
109 | }%
110 | \@xx{}%
111 | \@x{ {\CONSTANTS} R\_ReceiptSignature}%
112 | \@pvspace{8.0pt}%
113 | \@x{}\midbar\@xx{}%
114 | \@x{}%
115 | \@y{\@s{0}%
116 | Global variables
117 | }%
118 | \@xx{}%
119 | \@pvspace{8.0pt}%
120 | \@x{}%
121 | \@y{\@s{0}%
122 | A bag of records representing requests and responses sent from one process
123 | }%
124 | \@xx{}%
125 | \@x{}%
126 | \@y{\@s{0}%
127 | to another
128 | }%
129 | \@xx{}%
130 | \@x{ {\VARIABLE} messages}%
131 | \@pvspace{8.0pt}%
132 | \@x{}\midbar\@xx{}%
133 | \@x{}%
134 | \@y{\@s{0}%
135 | Sender variables
136 | }%
137 | \@xx{}%
138 | \@pvspace{8.0pt}%
139 | \@x{}%
140 | \@y{\@s{0}%
141 | State of the sender (\ensuremath{S\_Ready}, \ensuremath{S\_Waiting},
142 | \ensuremath{S\_Done})
143 | }%
144 | \@xx{}%
145 | \@x{ {\VARIABLE} senderState}%
146 | \@pvspace{8.0pt}%
147 | \@x{}%
148 | \@y{\@s{0}%
149 | All sender variables
150 | }%
151 | \@xx{}%
152 | \@x{ senderVars \.{\defeq} {\langle} senderState {\rangle}}%
153 | \@x{}\midbar\@xx{}%
154 | \@x{}%
155 | \@y{\@s{0}%
156 | The following variables are all per ledger (functions with domain
157 | \ensuremath{Ledger})
158 | }%
159 | \@xx{}%
160 | \@pvspace{8.0pt}%
161 | \@x{}%
162 | \@y{\@s{0}%
163 | The ledger state (\ensuremath{L\_Proposed}, \ensuremath{L\_Prepared},
164 | \ensuremath{L\_Executed} or \ensuremath{L\_Aborted})
165 | }%
166 | \@xx{}%
167 | \@x{ {\VARIABLE} ledgerState}%
168 | \@pvspace{8.0pt}%
169 | \@x{}%
170 | \@y{\@s{0}%
171 | All ledger variables
172 | }%
173 | \@xx{}%
174 | \@x{ ledgerVars \.{\defeq} {\langle} ledgerState {\rangle}}%
175 | \@x{}\midbar\@xx{}%
176 | \@x{}%
177 | \@y{\@s{0}%
178 | Notary variables
179 | }%
180 | \@xx{}%
181 | \@pvspace{8.0pt}%
182 | \@x{}%
183 | \@y{\@s{0}%
184 | State of the notary (\ensuremath{N\_Waiting}, \ensuremath{N\_Committed},
185 | \ensuremath{N\_Aborted})
186 | }%
187 | \@xx{}%
188 | \@x{ {\VARIABLE} notaryState}%
189 | \@pvspace{8.0pt}%
190 | \@x{}%
191 | \@y{\@s{0}%
192 | All notary variables
193 | }%
194 | \@xx{}%
195 | \@x{ notaryVars \.{\defeq} {\langle} notaryState {\rangle}}%
196 | \@x{}\midbar\@xx{}%
197 | \@pvspace{8.0pt}%
198 | \@x{}%
199 | \@y{\@s{0}%
200 | All variables; used for stuttering (asserting state hasn\mbox{'}t changed)
201 | }%
202 | \@xx{}%
203 | \@x{ vars \.{\defeq} {\langle} messages ,\, senderVars ,\, ledgerVars ,\,
204 | notaryVars {\rangle}}%
205 | \@pvspace{8.0pt}%
206 | \@x{}\midbar\@xx{}%
207 | \@x{}%
208 | \@y{\@s{0}%
209 | Helpers
210 | }%
211 | \@xx{}%
212 | \@pvspace{8.0pt}%
213 | \@x{}%
214 | \@y{\@s{0}%
215 | Add a set of new messages in transit
216 | }%
217 | \@xx{}%
218 | \@x{ Broadcast ( m ) \.{\defeq} messages \.{'} \.{=} messages \.{\oplus}
219 | SetToBag ( m )}%
220 | \@pvspace{8.0pt}%
221 | \@x{}%
222 | \@y{\@s{0}%
223 | Add a message to the bag of messages
224 | }%
225 | \@xx{}%
226 | \@x{ Send ( m ) \.{\defeq} Broadcast ( \{ m \} )}%
227 | \@pvspace{8.0pt}%
228 | \@x{}%
229 | \@y{\@s{0}%
230 | Remove a message from the bag of messages. Used when a process is done
231 | }%
232 | \@xx{}%
233 | \@x{}%
234 | \@y{\@s{0}%
235 | processing a message.
236 | }%
237 | \@xx{}%
238 | \@x{ Discard ( m ) \.{\defeq} messages \.{'} \.{=} messages \.{\ominus}
239 | SetToBag ( \{ m \} )}%
240 | \@pvspace{8.0pt}%
241 | \@x{}%
242 | \@y{\@s{0}%
243 | Respond to a message by sending multiple messages
244 | }%
245 | \@xx{}%
246 | \@x{ ReplyBroadcast ( responses ,\, request ) \.{\defeq}}%
247 | \@x{\@s{16.4} messages \.{'} \.{=} messages \.{\ominus} SetToBag ( \{ request
248 | \} ) \.{\oplus} SetToBag ( responses )}%
249 | \@pvspace{8.0pt}%
250 | \@x{}%
251 | \@y{\@s{0}%
252 | Combination of \ensuremath{Send} and \ensuremath{Discard
253 | }}%
254 | \@xx{}%
255 | \@x{ Reply ( response ,\, request ) \.{\defeq}}%
256 | \@x{\@s{16.4} ReplyBroadcast ( \{ response \} ,\, request )}%
257 | \@pvspace{16.0pt}%
258 | \@x{}%
259 | \@y{\@s{0}%
260 | Return the minimum value from a set, or undefined if the set is empty.
261 | }%
262 | \@xx{}%
263 | \@x{ Min ( s ) \.{\defeq} {\CHOOSE} x \.{\in} s \.{:} \A\, y \.{\in} s \.{:}
264 | x \.{\leq} y}%
265 | \@x{}%
266 | \@y{\@s{0}%
267 | Return the maximum value from a set, or undefined if the set is empty.
268 | }%
269 | \@xx{}%
270 | \@x{ Max ( s ) \.{\defeq} {\CHOOSE} x \.{\in} s \.{:} \A\, y \.{\in} s \.{:}
271 | x \.{\geq} y}%
272 | \@pvspace{8.0pt}%
273 | \@x{}%
274 | \@y{\@s{0}%
275 | Is a final ledger state
276 | }%
277 | \@xx{}%
278 | \@x{ IsFinalLedgerState ( i ) \.{\defeq} i \.{\in} \{ L\_Executed ,\,
279 | L\_Aborted \}}%
280 | \@pvspace{8.0pt}%
281 | \@x{}%
282 | \@y{\@s{0}%
283 | Sender
284 | }%
285 | \@xx{}%
286 | \@x{ Sender \.{\defeq} Min ( Participant )}%
287 | \@pvspace{8.0pt}%
288 | \@x{}%
289 | \@y{\@s{0}%
290 | Recipient
291 | }%
292 | \@xx{}%
293 | \@x{ Recipient \.{\defeq} Max ( Participant )}%
294 | \@pvspace{8.0pt}%
295 | \@x{}%
296 | \@y{\@s{0}%
297 | Set of connectors
298 | }%
299 | \@xx{}%
300 | \@x{ Connector \.{\defeq} Participant \.{\,\backslash\,} \{ Sender ,\,
301 | Recipient \}}%
302 | \@pvspace{8.0pt}%
303 | \@x{}\midbar\@xx{}%
304 | \@x{}%
305 | \@y{\@s{0}%
306 | Define type specification for all variables
307 | }%
308 | \@xx{}%
309 | \@pvspace{8.0pt}%
310 | \@x{ TypeOK \.{\defeq} \.{\land} IsABag ( messages )}%
311 | \@x{\@s{56.14} \.{\land} senderState \.{\in} \{ S\_Ready ,\, S\_Waiting ,\,
312 | S\_Done \}}%
313 | \@x{\@s{56.14} \.{\land} ledgerState\@s{3.06} \.{\in} [ Ledger
314 | \.{\rightarrow} \{ L\_Proposed ,\, L\_Prepared ,\, L\_Executed ,\,
315 | L\_Aborted \} ]}%
316 | \@pvspace{8.0pt}%
317 | \@x{ Consistency \.{\defeq}}%
318 | \@x{\@s{16.4} \A\, l1 ,\, l2 \.{\in} Ledger \.{:} {\lnot} \.{\land}
319 | ledgerState [ l1 ] \.{=} L\_Aborted}%
320 | \@x{\@s{104.69} \.{\land} ledgerState [ l2 ] \.{=} L\_Executed}%
321 | \@pvspace{8.0pt}%
322 | \@x{ Inv \.{\defeq} \.{\land} TypeOK}%
323 | \@x{\@s{34.04} \.{\land} Consistency}%
324 | \@pvspace{8.0pt}%
325 | \@x{}\midbar\@xx{}%
326 | \@x{}%
327 | \@y{\@s{0}%
328 | Define initial values for all variables
329 | }%
330 | \@xx{}%
331 | \@pvspace{8.0pt}%
332 | \@x{ InitSenderVars\@s{0.27} \.{\defeq} \.{\land} senderState \.{=} S\_Ready}%
333 | \@pvspace{8.0pt}%
334 | \@x{ InitLedgerVars\@s{1.67} \.{\defeq} \.{\land} ledgerState\@s{3.06} \.{=}
335 | [ i \.{\in} Ledger \.{\mapsto} L\_Proposed ]}%
336 | \@pvspace{8.0pt}%
337 | \@x{ InitNotaryVars \.{\defeq} \.{\land} notaryState \.{=} N\_Waiting}%
338 | \@pvspace{8.0pt}%
339 | \@x{ Init \.{\defeq} \.{\land} messages \.{=} EmptyBag}%
340 | \@x{\@s{35.70} \.{\land} InitSenderVars}%
341 | \@x{\@s{35.70} \.{\land} InitLedgerVars}%
342 | \@x{\@s{35.70} \.{\land} InitNotaryVars}%
343 | \@pvspace{8.0pt}%
344 | \@x{}\midbar\@xx{}%
345 | \@x{}%
346 | \@y{\@s{0}%
347 | Define state transitions
348 | }%
349 | \@xx{}%
350 | \@pvspace{8.0pt}%
351 | \@x{}%
352 | \@y{\@s{0}%
353 | Participant \ensuremath{i} starts off the chain
354 | }%
355 | \@xx{}%
356 | \@x{ Start ( i ) \.{\defeq}}%
357 | \@x{\@s{16.4} \.{\land} senderState \.{=} S\_Ready}%
358 | \@x{\@s{16.4} \.{\land} senderState \.{'} \.{=} S\_Waiting}%
359 | \@x{\@s{16.4} \.{\land} Send ( [ mtype\@s{9.58} \.{\mapsto} PrepareRequest
360 | ,\,}%
361 | \@x{\@s{56.16} msource \.{\mapsto} i ,\,}%
362 | \@x{\@s{56.16} mdest\@s{9.64} \.{\mapsto} i \.{+} 1 ] )}%
363 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} ledgerVars ,\, notaryVars
364 | {\rangle}}%
365 | \@pvspace{8.0pt}%
366 | \@x{}%
367 | \@y{\@s{0}%
368 | Notary times out
369 | }%
370 | \@xx{}%
371 | \@x{ NotaryTimeout \.{\defeq}}%
372 | \@x{\@s{16.4} \.{\land} notaryState \.{=} N\_Waiting}%
373 | \@x{\@s{16.4} \.{\land} notaryState \.{'} \.{=} N\_Aborted}%
374 | \@x{\@s{16.4} \.{\land} Broadcast (}%
375 | \@x{\@s{48.01} \{ [ mtype\@s{13.68} \.{\mapsto} AbortRequest ,\,}%
376 | \@x{\@s{55.78} msource\@s{4.10} \.{\mapsto} Notary ,\,}%
377 | \@x{\@s{55.78} mdest\@s{13.74} \.{\mapsto} k ] \.{:} k \.{\in} Ledger \} )}%
378 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars
379 | {\rangle}}%
380 | \@pvspace{8.0pt}%
381 | \@x{}%
382 | \@y{\@s{0}%
383 | Ledger spontaneously aborts
384 | }%
385 | \@xx{}%
386 | \@x{ LedgerAbort ( l ) \.{\defeq}}%
387 | \@x{\@s{16.4} \.{\land} ledgerState [ l ] \.{=} L\_Proposed}%
388 | \@x{\@s{16.4} \.{\land} ledgerState \.{'} \.{=} [ ledgerState {\EXCEPT}
389 | {\bang} [ l ] \.{=} L\_Aborted ]}%
390 | \@x{\@s{16.4} \.{\land} Send ( [ mtype\@s{9.58} \.{\mapsto} AbortNotify ,\,}%
391 | \@x{\@s{56.16} msource \.{\mapsto} l ,\,}%
392 | \@x{\@s{56.16} mdest\@s{9.64} \.{\mapsto} l \.{-} 1 ] )}%
393 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, notaryVars
394 | {\rangle}}%
395 | \@pvspace{8.0pt}%
396 | \@x{}\midbar\@xx{}%
397 | \@x{}%
398 | \@y{\@s{0}%
399 | Message handlers
400 | }%
401 | \@xx{}%
402 | \@x{}%
403 | \@y{\@s{0}%
404 | \ensuremath{i \.{=}} recipient, \ensuremath{j \.{=}} sender, \ensuremath{m
405 | \.{=}} message
406 | }%
407 | \@xx{}%
408 | \@pvspace{8.0pt}%
409 | \@x{}%
410 | \@y{\@s{0}%
411 | Ledger \ensuremath{i} receives a Prepare request from process \ensuremath{j
412 | }}%
413 | \@xx{}%
414 | \@x{ LedgerHandlePrepareRequest ( i ,\, j ,\, m ) \.{\defeq}}%
415 | \@x{\@s{16.4} \.{\LET} valid \.{\defeq} \.{\land} ledgerState [ i ] \.{=}
416 | L\_Proposed}%
417 | \@x{\@s{77.16} \.{\land} j \.{=} i \.{-} 1}%
418 | \@x{\@s{16.4} \.{\IN} \.{\lor} \.{\land} valid}%
419 | \@x{\@s{47.91} \.{\land} ledgerState \.{'} \.{=} [ ledgerState {\EXCEPT}
420 | {\bang} [ i ] \.{=} L\_Prepared ]}%
421 | \@x{\@s{47.91} \.{\land} Reply ( [ mtype\@s{9.58} \.{\mapsto} PrepareNotify
422 | ,\,}%
423 | \@x{\@s{90.47} msource \.{\mapsto} i ,\,}%
424 | \@x{\@s{90.47} mdest\@s{9.64} \.{\mapsto} i \.{+} 1 ] ,\, m )}%
425 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, notaryVars
426 | {\rangle}}%
427 | \@x{\@s{36.79} \.{\lor} \.{\land} {\lnot} valid}%
428 | \@x{\@s{47.91} \.{\land} Discard ( m )}%
429 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
430 | notaryVars {\rangle}}%
431 | \@pvspace{8.0pt}%
432 | \@x{}%
433 | \@y{\@s{0}%
434 | Ledger \ensuremath{i} receives an Execute request from process \ensuremath{j
435 | }}%
436 | \@xx{}%
437 | \@x{ LedgerHandleExecuteRequest ( i ,\, j ,\, m ) \.{\defeq}}%
438 | \@x{\@s{16.4} \.{\LET} valid \.{\defeq} \.{\land} ledgerState [ i ] \.{=}
439 | L\_Prepared}%
440 | \@x{\@s{77.16} \.{\land} j \.{=} Notary}%
441 | \@x{\@s{16.4} \.{\IN} \.{\lor} \.{\land} valid}%
442 | \@x{\@s{47.91} \.{\land} ledgerState \.{'} \.{=} [ ledgerState {\EXCEPT}
443 | {\bang} [ i ] \.{=} L\_Executed ]}%
444 | \@x{\@s{47.91} \.{\land} Reply ( [ mtype\@s{9.58} \.{\mapsto} ExecuteNotify
445 | ,\,}%
446 | \@x{\@s{90.47} msource \.{\mapsto} i ,\,}%
447 | \@x{\@s{90.47} mdest\@s{9.64} \.{\mapsto} i \.{-} 1 ] ,\, m )}%
448 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, notaryVars
449 | {\rangle}}%
450 | \@x{\@s{36.79} \.{\lor} \.{\land} {\lnot} valid}%
451 | \@x{\@s{47.91} \.{\land} Discard ( m )}%
452 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
453 | notaryVars {\rangle}}%
454 | \@pvspace{8.0pt}%
455 | \@x{}%
456 | \@y{\@s{0}%
457 | Ledger \ensuremath{i} receives an Abort request from process \ensuremath{j
458 | }}%
459 | \@xx{}%
460 | \@x{ LedgerHandleAbortRequest ( i ,\, j ,\, m ) \.{\defeq}}%
461 | \@x{\@s{16.4} \.{\LET} valid \.{\defeq} \.{\land} \.{\lor} ledgerState [ i ]
462 | \.{=} L\_Proposed}%
463 | \@x{\@s{88.27} \.{\lor} ledgerState [ i ] \.{=} L\_Prepared}%
464 | \@x{\@s{77.16} \.{\land} j \.{=} Notary}%
465 | \@x{\@s{16.4} \.{\IN} \.{\lor} \.{\land} valid}%
466 | \@x{\@s{47.91} \.{\land} ledgerState \.{'} \.{=} [ ledgerState {\EXCEPT}
467 | {\bang} [ i ] \.{=} L\_Aborted ]}%
468 | \@x{\@s{47.91} \.{\land} Reply ( [ mtype\@s{9.58} \.{\mapsto} AbortNotify
469 | ,\,}%
470 | \@x{\@s{90.47} msource \.{\mapsto} i ,\,}%
471 | \@x{\@s{90.47} mdest\@s{9.64} \.{\mapsto} i \.{-} 1 ] ,\, m )}%
472 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, notaryVars
473 | {\rangle}}%
474 | \@x{\@s{36.79} \.{\lor} \.{\land} {\lnot} valid}%
475 | \@x{\@s{47.91} \.{\land} Discard ( m )}%
476 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
477 | notaryVars {\rangle}}%
478 | \@pvspace{8.0pt}%
479 | \@x{}%
480 | \@y{\@s{0}%
481 | Ledger \ensuremath{i} receives a message
482 | }%
483 | \@xx{}%
484 | \@x{ LedgerReceive ( i ,\, j ,\, m ) \.{\defeq}}%
485 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} PrepareRequest}%
486 | \@x{\@s{27.51} \.{\land} LedgerHandlePrepareRequest ( i ,\, j ,\, m )}%
487 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} ExecuteRequest}%
488 | \@x{\@s{27.51} \.{\land} LedgerHandleExecuteRequest ( i ,\, j ,\, m )}%
489 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} AbortRequest}%
490 | \@x{\@s{27.51} \.{\land} LedgerHandleAbortRequest ( i ,\, j ,\, m )}%
491 | \@pvspace{8.0pt}%
492 | \@x{}%
493 | \@y{\@s{0}%
494 | Ledger \ensuremath{j} notifies sender that the transfer is executed
495 | }%
496 | \@xx{}%
497 | \@x{ SenderHandleExecuteNotify ( i ,\, j ,\, m ) \.{\defeq}}%
498 | \@x{\@s{16.4} \.{\lor} \.{\land} senderState \.{=} S\_Waiting}%
499 | \@x{\@s{27.51} \.{\land} senderState \.{'} \.{=} S\_Done}%
500 | \@x{\@s{27.51} \.{\land} Discard ( m )}%
501 | \@x{\@s{27.51} \.{\land} {\UNCHANGED} {\langle} ledgerVars ,\, notaryVars
502 | {\rangle}}%
503 | \@x{\@s{16.4} \.{\lor} \.{\land} senderState \.{\neq} S\_Waiting}%
504 | \@x{\@s{27.51} \.{\land} Discard ( m )}%
505 | \@x{\@s{27.51} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
506 | notaryVars {\rangle}}%
507 | \@pvspace{8.0pt}%
508 | \@x{}%
509 | \@y{\@s{0}%
510 | Ledger \ensuremath{j} notifies sender that the transfer is aborted
511 | }%
512 | \@xx{}%
513 | \@x{ SenderHandleAbortNotify ( i ,\, j ,\, m ) \.{\defeq}}%
514 | \@x{\@s{16.4} \.{\LET} isSenderWaiting \.{\defeq} \.{\lor} senderState \.{=}
515 | S\_Waiting}%
516 | \@x{\@s{128.27} \.{\lor} senderState \.{=} S\_Ready}%
517 | \@x{\@s{16.4} \.{\IN} \.{\lor} \.{\land} isSenderWaiting}%
518 | \@x{\@s{47.91} \.{\land} senderState \.{'} \.{=} S\_Done}%
519 | \@x{\@s{47.91} \.{\land} Discard ( m )}%
520 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} ledgerVars ,\, notaryVars
521 | {\rangle}}%
522 | \@x{\@s{36.79} \.{\lor} \.{\land} {\lnot} isSenderWaiting}%
523 | \@x{\@s{47.91} \.{\land} Discard ( m )}%
524 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
525 | notaryVars {\rangle}}%
526 | \@pvspace{8.0pt}%
527 | \@x{}%
528 | \@y{\@s{0}%
529 | Sender receives a message
530 | }%
531 | \@xx{}%
532 | \@x{ SenderReceive ( i ,\, j ,\, m ) \.{\defeq}}%
533 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} ExecuteNotify}%
534 | \@x{\@s{27.51} \.{\land} SenderHandleExecuteNotify ( i ,\, j ,\, m )}%
535 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} AbortNotify}%
536 | \@x{\@s{27.51} \.{\land} SenderHandleAbortNotify ( i ,\, j ,\, m )}%
537 | \@pvspace{8.0pt}%
538 | \@x{}%
539 | \@y{\@s{0}%
540 | Ledger \ensuremath{j} notifies recipient that the transfer is prepared
541 | }%
542 | \@xx{}%
543 | \@x{ RecipientHandlePrepareNotify ( i ,\, j ,\, m ) \.{\defeq}}%
544 | \@x{\@s{16.4} \.{\land} Reply ( [ mtype\@s{12.29} \.{\mapsto}
545 | SubmitReceiptRequest ,\,}%
546 | \@x{\@s{58.96} msource\@s{2.71} \.{\mapsto} i ,\,}%
547 | \@x{\@s{58.96} mdest\@s{12.35} \.{\mapsto} Notary ,\,}%
548 | \@x{\@s{58.96} mreceipt\@s{1.49} \.{\mapsto} R\_ReceiptSignature ] ,\, m )}%
549 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
550 | notaryVars {\rangle}}%
551 | \@pvspace{8.0pt}%
552 | \@x{}%
553 | \@y{\@s{0}%
554 | Recipient receives a message
555 | }%
556 | \@xx{}%
557 | \@x{ RecipientReceive ( i ,\, j ,\, m ) \.{\defeq}}%
558 | \@x{\@s{16.4} \.{\land} m . mtype \.{=} PrepareNotify}%
559 | \@x{\@s{16.4} \.{\land} RecipientHandlePrepareNotify ( i ,\, j ,\, m )}%
560 | \@pvspace{8.0pt}%
561 | \@x{}%
562 | \@y{\@s{0}%
563 | Ledger \ensuremath{j} notifies connector \ensuremath{i} that the transfer is
564 | prepared
565 | }%
566 | \@xx{}%
567 | \@x{ ConnectorHandlePrepareNotify ( i ,\, j ,\, m ) \.{\defeq}}%
568 | \@x{\@s{16.4} \.{\land} Reply ( [ mtype\@s{9.58} \.{\mapsto} PrepareRequest
569 | ,\,}%
570 | \@x{\@s{58.96} msource \.{\mapsto} i ,\,}%
571 | \@x{\@s{58.96} mdest\@s{9.64} \.{\mapsto} i \.{+} 1 ] ,\, m )}%
572 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
573 | notaryVars {\rangle}}%
574 | \@pvspace{8.0pt}%
575 | \@x{}%
576 | \@y{\@s{0}%
577 | Ledger \ensuremath{j} notifies connector \ensuremath{i} that the transfer is
578 | executed
579 | }%
580 | \@xx{}%
581 | \@x{ ConnectorHandleExecuteNotify ( i ,\, j ,\, m ) \.{\defeq}}%
582 | \@x{\@s{16.4} \.{\land} Reply ( [ mtype\@s{9.58} \.{\mapsto} ExecuteRequest
583 | ,\,}%
584 | \@x{\@s{58.96} msource \.{\mapsto} i ,\,}%
585 | \@x{\@s{58.96} mdest\@s{9.64} \.{\mapsto} i \.{-} 1 ] ,\, m )}%
586 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
587 | notaryVars {\rangle}}%
588 | \@pvspace{8.0pt}%
589 | \@x{}%
590 | \@y{\@s{0}%
591 | Ledger \ensuremath{j} notifies connector \ensuremath{i} that the transfer is
592 | aborted
593 | }%
594 | \@xx{}%
595 | \@x{ ConnectorHandleAbortNotify ( i ,\, j ,\, m ) \.{\defeq}}%
596 | \@x{\@s{16.4} \.{\land} Discard ( m )}%
597 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
598 | notaryVars {\rangle}}%
599 | \@pvspace{8.0pt}%
600 | \@x{}%
601 | \@y{\@s{0}%
602 | Connector receives a message
603 | }%
604 | \@xx{}%
605 | \@x{ ConnectorReceive ( i ,\, j ,\, m ) \.{\defeq}}%
606 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} PrepareNotify}%
607 | \@x{\@s{27.51} \.{\land} ConnectorHandlePrepareNotify ( i ,\, j ,\, m )}%
608 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} ExecuteNotify}%
609 | \@x{\@s{27.51} \.{\land} ConnectorHandleExecuteNotify ( i ,\, j ,\, m )}%
610 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} AbortNotify}%
611 | \@x{\@s{27.51} \.{\land} ConnectorHandleAbortNotify ( i ,\, j ,\, m )}%
612 | \@pvspace{8.0pt}%
613 | \@x{}%
614 | \@y{\@s{0}%
615 | Notary receives a signed receipt
616 | }%
617 | \@xx{}%
618 | \@x{ NotaryHandleSubmitReceiptRequest ( i ,\, j ,\, m ) \.{\defeq}}%
619 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mreceipt \.{=} R\_ReceiptSignature}%
620 | \@x{\@s{27.51} \.{\land} notaryState \.{=} N\_Waiting}%
621 | \@x{\@s{27.51} \.{\land} notaryState \.{'} \.{=} N\_Committed}%
622 | \@x{\@s{27.51} \.{\land} ReplyBroadcast (}%
623 | \@x{\@s{46.82} \{ [ mtype\@s{13.68} \.{\mapsto} ExecuteRequest ,\,}%
624 | \@x{\@s{54.59} msource\@s{4.1} \.{\mapsto} i ,\,}%
625 | \@x{\@s{54.59} mdest\@s{13.74} \.{\mapsto} k ] \.{:} k \.{\in} Ledger \} ,\,
626 | m )}%
627 | \@x{\@s{27.51} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars
628 | {\rangle}}%
629 | \@x{\@s{16.4} \.{\lor} \.{\land} notaryState \.{\neq} N\_Waiting}%
630 | \@x{\@s{27.51} \.{\land} Discard ( m )}%
631 | \@x{\@s{27.51} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars ,\,
632 | notaryVars {\rangle}}%
633 | \@pvspace{8.0pt}%
634 | \@x{}%
635 | \@y{\@s{0}%
636 | Notary receives a message
637 | }%
638 | \@xx{}%
639 | \@x{ NotaryReceive ( i ,\, j ,\, m ) \.{\defeq}}%
640 | \@x{\@s{16.4} \.{\land} m . mtype \.{=} SubmitReceiptRequest}%
641 | \@x{\@s{16.4} \.{\land} NotaryHandleSubmitReceiptRequest ( i ,\, j ,\, m )}%
642 | \@pvspace{8.0pt}%
643 | \@x{}%
644 | \@y{\@s{0}%
645 | Receive a message
646 | }%
647 | \@xx{}%
648 | \@x{ Receive ( m ) \.{\defeq}}%
649 | \@x{\@s{16.4} \.{\LET} i\@s{0.42} \.{\defeq} m . mdest}%
650 | \@x{\@s{36.79} j \.{\defeq} m . msource}%
651 | \@x{\@s{16.4} \.{\IN} \.{\lor} \.{\land} i \.{\in} Ledger}%
652 | \@x{\@s{47.91} \.{\land} LedgerReceive ( i ,\, j ,\, m )}%
653 | \@x{\@s{36.79} \.{\lor} \.{\land} i \.{=} Sender}%
654 | \@x{\@s{47.91} \.{\land} SenderReceive ( i ,\, j ,\, m )}%
655 | \@x{\@s{36.79} \.{\lor} \.{\land} i \.{=} Recipient}%
656 | \@x{\@s{47.91} \.{\land} RecipientReceive ( i ,\, j ,\, m )}%
657 | \@x{\@s{36.79} \.{\lor} \.{\land} i \.{\in} Connector}%
658 | \@x{\@s{47.91} \.{\land} ConnectorReceive ( i ,\, j ,\, m )}%
659 | \@x{\@s{36.79} \.{\lor} \.{\land} i \.{=} Notary}%
660 | \@x{\@s{47.91} \.{\land} NotaryReceive ( i ,\, j ,\, m )}%
661 | \@pvspace{8.0pt}%
662 | \@x{}%
663 | \@y{\@s{0}%
664 | End of message handlers
665 | }%
666 | \@xx{}%
667 | \@x{}\midbar\@xx{}%
668 | \@x{}%
669 | \@y{\@s{0}%
670 | Defines how the variables may transition
671 | }%
672 | \@xx{}%
673 | \@pvspace{8.0pt}%
674 | \@x{ Termination \.{\defeq}}%
675 | \@x{\@s{16.4} \.{\land} \A\, l \.{\in} Ledger \.{:} IsFinalLedgerState (
676 | ledgerState [ l ] )}%
677 | \@x{\@s{16.4} \.{\land} senderState \.{=} S\_Done}%
678 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} vars}%
679 | \@pvspace{8.0pt}%
680 | \@x{ Next \.{\defeq} \.{\lor} Start ( Sender )}%
681 | \@x{\@s{39.83} \.{\lor} NotaryTimeout}%
682 | \@x{\@s{39.83} \.{\lor} \E\, l\@s{5.35} \.{\in} Ledger \.{:} LedgerAbort ( l
683 | )}%
684 | \@x{\@s{39.83} \.{\lor} \E\, m \.{\in} {\DOMAIN} messages \.{:} Receive ( m
685 | )}%
686 | \@x{\@s{39.83} \.{\lor} Termination}%
687 | \@pvspace{8.0pt}%
688 | \@x{}%
689 | \@y{\@s{0}%
690 | The specification must start with the initial state and transition according
691 | }%
692 | \@xx{}%
693 | \@x{}%
694 | \@y{\@s{0}%
695 | to \ensuremath{Next}.
696 | }%
697 | \@xx{}%
698 | \@x{ Spec \.{\defeq} Init \.{\land} {\Box} [ Next ]_{ vars}}%
699 | \@pvspace{8.0pt}%
700 | \@x{}\bottombar\@xx{}%
701 | \end{document}
--------------------------------------------------------------------------------
/specs/universal.tex:
--------------------------------------------------------------------------------
1 | \batchmode %% Suppresses most terminal output.
2 | \documentclass[letterpaper,twocolumn,10pt]{article}
3 | \usepackage{color}
4 | \usepackage{ilpspec}
5 | % \usepackage{usenix}
6 | \definecolor{boxshade}{gray}{0.95}
7 |
8 | \setlength{\headheight}{0.0in}
9 |
10 | \usepackage{latexsym}
11 | \usepackage{ifthen}
12 | % \usepackage{color}
13 | \usepackage{tlatex}
14 |
15 | \begin{document}
16 | \onecolumn
17 | \appendix
18 | \stepcounter{section}
19 | \stepcounter{subsection}
20 | \stepcounter{subsection}
21 | \stepcounter{subsection}
22 | \setcounter{page}{19}
23 | \subsection{Formal Specification: Universal mode}
24 | \label{sec:universal-spec}
25 | \tlatex
26 | \setboolean{shading}{true}
27 | \@x{}\moduleLeftDash\@xx{ {\MODULE} Universal}\moduleRightDash\@xx{}%
28 | \begin{lcom}{0}%
29 | \begin{cpar}{0}{T}{F}{2.5}{0}{}%
30 | Formal Specification in TLA\ensuremath{\.{\mbox{}^+}} of the
31 | Interledger Protocol \ensuremath{Universal} (\ensuremath{ILP}/\ensuremath{U})
32 | \end{cpar}%
33 | \vshade{10.0}%
34 | \begin{cpar}{1}{F}{F}{0}{0}{}%
35 | \begin{minipage}[t]{\linewidth}
36 | \begin{verbatim}
37 | Modeled after the excellent Raft specification by Diego Ongaro.
38 | Available at https://github.com/ongardie/raft.tla
39 | \end{verbatim}
40 | \end{minipage}
41 | \end{cpar}%
42 | \vshade{5.0}%
43 | \begin{cpar}{0}{F}{F}{0}{0}{}%
44 | \begin{minipage}[t]{\linewidth}
45 | \begin{verbatim}
46 | Copyright 2014 Diego Ongaro.
47 | This work is licensed under the Creative Commons Attribution-4.0
48 | International License https://creativecommons.org/licenses/by/4.0/
49 | \end{verbatim}
50 | \end{minipage}
51 | \end{cpar}%
52 | \end{lcom}%
53 | \@pvspace{8.0pt}%
54 | \@x{ {\EXTENDS} Naturals ,\, Sequences ,\, FiniteSets ,\, Bags ,\, TLC}%
55 | \@pvspace{8.0pt}%
56 | \@x{}%
57 | \@y{\@s{0}%
58 | The set of ledger \ensuremath{IDs
59 | }}%
60 | \@xx{}%
61 | \@x{ {\CONSTANTS} Ledger}%
62 | \@pvspace{8.0pt}%
63 | \@x{}%
64 | \@y{\@s{0}%
65 | The set of participant \ensuremath{IDs
66 | }}%
67 | \@xx{}%
68 | \@x{ {\CONSTANTS} Participant}%
69 | \@pvspace{8.0pt}%
70 | \@x{}%
71 | \@y{\@s{0}%
72 | Sender states
73 | }%
74 | \@xx{}%
75 | \@x{ {\CONSTANTS} S\_Ready ,\, S\_ProposalWaiting ,\, S\_Waiting ,\, S\_Done}%
76 | \@pvspace{8.0pt}%
77 | \@x{}%
78 | \@y{\@s{0}%
79 | Connector states
80 | }%
81 | \@xx{}%
82 | \@x{ {\CONSTANTS} C\_Ready ,\, C\_Proposed}%
83 | \@pvspace{8.0pt}%
84 | \@x{}%
85 | \@y{\@s{0}%
86 | Ledger states
87 | }%
88 | \@xx{}%
89 | \@x{ {\CONSTANTS} L\_Proposed ,\, L\_Prepared ,\, L\_Executed ,\, L\_Aborted}%
90 | \@pvspace{8.0pt}%
91 | \@x{}%
92 | \@y{\@s{0}%
93 | Message types
94 | }%
95 | \@xx{}%
96 | \@x{ {\CONSTANTS} PrepareRequest ,\, ExecuteRequest ,\, AbortRequest ,\,}%
97 | \@x{\@s{54.75} PrepareNotify ,\, ExecuteNotify ,\, AbortNotify ,\,}%
98 | \@x{\@s{54.75} SubpaymentProposalRequest ,\, SubpaymentProposalResponse}%
99 | \@pvspace{8.0pt}%
100 | \@x{}%
101 | \@y{\@s{0}%
102 | Receipt signature
103 | }%
104 | \@xx{}%
105 | \@x{ {\CONSTANTS} R\_ReceiptSignature}%
106 | \@pvspace{8.0pt}%
107 | \@x{}\midbar\@xx{}%
108 | \@x{}%
109 | \@y{\@s{0}%
110 | Global variables
111 | }%
112 | \@xx{}%
113 | \@pvspace{8.0pt}%
114 | \@x{}%
115 | \@y{\@s{0}%
116 | Under synchrony we are allowed to have a global clock
117 | }%
118 | \@xx{}%
119 | \@x{ {\VARIABLE} clock}%
120 | \@pvspace{8.0pt}%
121 | \@x{}%
122 | \@y{\@s{0}%
123 | A bag of records representing requests and responses sent from one process
124 | }%
125 | \@xx{}%
126 | \@x{}%
127 | \@y{\@s{0}%
128 | to another
129 | }%
130 | \@xx{}%
131 | \@x{ {\VARIABLE} messages}%
132 | \@pvspace{8.0pt}%
133 | \@x{}\midbar\@xx{}%
134 | \@x{}%
135 | \@y{\@s{0}%
136 | Sender variables
137 | }%
138 | \@xx{}%
139 | \@pvspace{8.0pt}%
140 | \@x{}%
141 | \@y{\@s{0}%
142 | State of the sender (\ensuremath{S\_Ready}, \ensuremath{S\_Waiting},
143 | \ensuremath{S\_Done})
144 | }%
145 | \@xx{}%
146 | \@x{ {\VARIABLE} senderState}%
147 | \@pvspace{8.0pt}%
148 | \@x{}%
149 | \@y{\@s{0}%
150 | Whether the sender has received a response from a given connector
151 | }%
152 | \@xx{}%
153 | \@x{ {\VARIABLE} senderProposalResponses}%
154 | \@pvspace{8.0pt}%
155 | \@x{}%
156 | \@y{\@s{0}%
157 | All sender variables
158 | }%
159 | \@xx{}%
160 | \@x{ senderVars \.{\defeq} {\langle} senderState ,\, senderProposalResponses
161 | {\rangle}}%
162 | \@x{}\midbar\@xx{}%
163 | \@x{}%
164 | \@y{\@s{0}%
165 | Connector variables
166 | }%
167 | \@xx{}%
168 | \@pvspace{8.0pt}%
169 | \@x{}%
170 | \@y{\@s{0}%
171 | State of the connector (\ensuremath{C\_Ready}, \ensuremath{C\_Proposed})
172 | }%
173 | \@xx{}%
174 | \@x{ {\VARIABLE} connectorState}%
175 | \@pvspace{8.0pt}%
176 | \@x{}%
177 | \@y{\@s{0}%
178 | All sender variables
179 | }%
180 | \@xx{}%
181 | \@x{ connectorVars \.{\defeq} {\langle} connectorState {\rangle}}%
182 | \@x{}\midbar\@xx{}%
183 | \@x{}%
184 | \@y{\@s{0}%
185 | The following variables are all per ledger (functions with domain
186 | \ensuremath{Ledger})
187 | }%
188 | \@xx{}%
189 | \@pvspace{8.0pt}%
190 | \@x{}%
191 | \@y{\@s{0}%
192 | The ledger state (\ensuremath{L\_Proposed}, \ensuremath{L\_Prepared},
193 | \ensuremath{L\_Executed} or \ensuremath{L\_Aborted})
194 | }%
195 | \@xx{}%
196 | \@x{ {\VARIABLE} ledgerState}%
197 | \@pvspace{8.0pt}%
198 | \@x{}%
199 | \@y{\@s{0}%
200 | The timeouts for each of the the transfers
201 | }%
202 | \@xx{}%
203 | \@x{ {\VARIABLE} ledgerExpiration}%
204 | \@pvspace{8.0pt}%
205 | \@x{}%
206 | \@y{\@s{0}%
207 | All ledger variables
208 | }%
209 | \@xx{}%
210 | \@x{ ledgerVars \.{\defeq} {\langle} ledgerState ,\, ledgerExpiration
211 | {\rangle}}%
212 | \@x{}\midbar\@xx{}%
213 | \@pvspace{8.0pt}%
214 | \@x{}%
215 | \@y{\@s{0}%
216 | All variables; used for stuttering (asserting state hasn\mbox{'}t changed)
217 | }%
218 | \@xx{}%
219 | \@x{ vars \.{\defeq} {\langle} clock ,\, messages ,\, senderVars ,\,
220 | connectorVars ,\, ledgerVars {\rangle}}%
221 | \@pvspace{8.0pt}%
222 | \@x{}\midbar\@xx{}%
223 | \@x{}%
224 | \@y{\@s{0}%
225 | Helpers
226 | }%
227 | \@xx{}%
228 | \@pvspace{8.0pt}%
229 | \@x{}%
230 | \@y{\@s{0}%
231 | Add a set of new messages in transit
232 | }%
233 | \@xx{}%
234 | \@x{ Broadcast ( m ) \.{\defeq} messages \.{'} \.{=} messages \.{\oplus}
235 | SetToBag ( m )}%
236 | \@pvspace{8.0pt}%
237 | \@x{}%
238 | \@y{\@s{0}%
239 | Add a message to the bag of messages
240 | }%
241 | \@xx{}%
242 | \@x{ Send ( m ) \.{\defeq} Broadcast ( \{ m \} )}%
243 | \@pvspace{8.0pt}%
244 | \@x{}%
245 | \@y{\@s{0}%
246 | Remove a message from the bag of messages. Used when a process is done
247 | }%
248 | \@xx{}%
249 | \@x{}%
250 | \@y{\@s{0}%
251 | processing a message.
252 | }%
253 | \@xx{}%
254 | \@x{ Discard ( m ) \.{\defeq} messages \.{'} \.{=} messages \.{\ominus}
255 | SetToBag ( \{ m \} )}%
256 | \@pvspace{8.0pt}%
257 | \@x{}%
258 | \@y{\@s{0}%
259 | Respond to a message by sending multiple messages
260 | }%
261 | \@xx{}%
262 | \@x{ ReplyBroadcast ( responses ,\, request ) \.{\defeq}}%
263 | \@x{\@s{16.4} messages \.{'} \.{=} messages \.{\ominus} SetToBag ( \{ request
264 | \} ) \.{\oplus} SetToBag ( responses )}%
265 | \@pvspace{8.0pt}%
266 | \@x{}%
267 | \@y{\@s{0}%
268 | Combination of \ensuremath{Send} and \ensuremath{Discard
269 | }}%
270 | \@xx{}%
271 | \@x{ Reply ( response ,\, request ) \.{\defeq}}%
272 | \@x{\@s{16.4} ReplyBroadcast ( \{ response \} ,\, request )}%
273 | \@pvspace{16.0pt}%
274 | \@x{}%
275 | \@y{\@s{0}%
276 | Return the minimum value from a set, or undefined if the set is empty.
277 | }%
278 | \@xx{}%
279 | \@x{ Min ( s ) \.{\defeq} {\CHOOSE} x \.{\in} s \.{:} \A\, y \.{\in} s \.{:}
280 | x \.{\leq} y}%
281 | \@x{}%
282 | \@y{\@s{0}%
283 | Return the maximum value from a set, or undefined if the set is empty.
284 | }%
285 | \@xx{}%
286 | \@x{ Max ( s ) \.{\defeq} {\CHOOSE} x \.{\in} s \.{:} \A\, y \.{\in} s \.{:}
287 | x \.{\geq} y}%
288 | \@pvspace{8.0pt}%
289 | \@x{}%
290 | \@y{\@s{0}%
291 | Is a final ledger state
292 | }%
293 | \@xx{}%
294 | \@x{ IsFinalLedgerState ( i ) \.{\defeq} i \.{\in} \{ L\_Executed ,\,
295 | L\_Aborted \}}%
296 | \@pvspace{8.0pt}%
297 | \@x{}%
298 | \@y{\@s{0}%
299 | Sender
300 | }%
301 | \@xx{}%
302 | \@x{ Sender \.{\defeq} Min ( Participant )}%
303 | \@pvspace{8.0pt}%
304 | \@x{}%
305 | \@y{\@s{0}%
306 | Recipient
307 | }%
308 | \@xx{}%
309 | \@x{ Recipient \.{\defeq} Max ( Participant )}%
310 | \@pvspace{8.0pt}%
311 | \@x{}%
312 | \@y{\@s{0}%
313 | Set of connectors
314 | }%
315 | \@xx{}%
316 | \@x{ Connector \.{\defeq} Participant \.{\,\backslash\,} \{ Sender ,\,
317 | Recipient \}}%
318 | \@pvspace{8.0pt}%
319 | \@x{}%
320 | \@y{\@s{0}%
321 | The clock value we expect to be at after the proposal phase
322 | }%
323 | \@xx{}%
324 | \@x{ ClockAfterProposal \.{\defeq} 2 \.{*} Cardinality ( Connector ) \.{+} 2}%
325 | \@pvspace{8.0pt}%
326 | \@x{}%
327 | \@y{\@s{0}%
328 | The clock value we expect after the preparation phase
329 | }%
330 | \@xx{}%
331 | \@x{ ClockAfterPrepare \.{\defeq} ClockAfterProposal \.{+} 2 \.{*}
332 | Cardinality ( Ledger ) \.{+} 1}%
333 | \@pvspace{8.0pt}%
334 | \@x{}%
335 | \@y{\@s{0}%
336 | The clock value we expect to be at after the execution phase
337 | }%
338 | \@xx{}%
339 | \@x{ ClockAfterExecution \.{\defeq} ClockAfterPrepare \.{+} 2 \.{*}
340 | Cardinality ( Ledger ) \.{+} 1}%
341 | \@x{}\midbar\@xx{}%
342 | \@x{}%
343 | \@y{\@s{0}%
344 | Define type specification for all variables
345 | }%
346 | \@xx{}%
347 | \@pvspace{8.0pt}%
348 | \@x{ TypeOK \.{\defeq} \.{\land} clock \.{\in} Nat}%
349 | \@x{\@s{56.14} \.{\land} IsABag ( messages )}%
350 | \@x{\@s{56.14} \.{\land} senderState \.{\in} \{ S\_Ready ,\,
351 | S\_ProposalWaiting ,\, S\_Waiting ,\, S\_Done \}}%
352 | \@x{\@s{56.14} \.{\land} senderProposalResponses \.{\in} [ Connector
353 | \.{\rightarrow} {\BOOLEAN} ]}%
354 | \@x{\@s{56.14} \.{\land} connectorState \.{\in} [ Connector \.{\rightarrow}
355 | \{ C\_Ready ,\, C\_Proposed \} ]}%
356 | \@x{\@s{56.14} \.{\land} ledgerState \.{\in} [ Ledger \.{\rightarrow} \{
357 | L\_Proposed ,\, L\_Prepared ,\, L\_Executed ,\, L\_Aborted \} ]}%
358 | \@x{\@s{56.14} \.{\land} ledgerExpiration \.{\in} [ Ledger \.{\rightarrow}
359 | Nat ]}%
360 | \@pvspace{8.0pt}%
361 | \@x{ Consistency \.{\defeq}}%
362 | \@x{\@s{16.4} \A\, l1 ,\, l2 \.{\in} Ledger \.{:} {\lnot} \.{\land}
363 | ledgerState [ l1 ] \.{=} L\_Aborted}%
364 | \@x{\@s{104.69} \.{\land} ledgerState [ l2 ] \.{=} L\_Executed}%
365 | \@pvspace{8.0pt}%
366 | \@x{ Inv \.{\defeq} \.{\land} TypeOK}%
367 | \@x{\@s{34.04} \.{\land} Consistency}%
368 | \@pvspace{8.0pt}%
369 | \@x{}\midbar\@xx{}%
370 | \@x{}%
371 | \@y{\@s{0}%
372 | Define initial values for all variables
373 | }%
374 | \@xx{}%
375 | \@pvspace{8.0pt}%
376 | \@x{ InitSenderVars \.{\defeq} \.{\land} senderState \.{=} S\_Ready}%
377 | \@x{\@s{85.43} \.{\land} senderProposalResponses \.{=} [ i \.{\in} Connector
378 | \.{\mapsto} {\FALSE} ]}%
379 | \@pvspace{8.0pt}%
380 | \@x{ InitConnectorVars \.{\defeq} connectorState \.{=} [ i \.{\in} Connector
381 | \.{\mapsto} C\_Ready ]}%
382 | \@pvspace{8.0pt}%
383 | \@x{ InitLedgerVars \.{\defeq} \.{\land} ledgerState \.{=} [ i\@s{3.38}
384 | \.{\in} Ledger \.{\mapsto} L\_Proposed ]}%
385 | \@x{\@s{84.03} \.{\land} ledgerExpiration \.{=} [ i \.{\in} Ledger
386 | \.{\mapsto} ClockAfterExecution \.{-} i ]}%
387 | \@pvspace{8.0pt}%
388 | \@x{ Init \.{\defeq} \.{\land} clock \.{=} 0}%
389 | \@x{\@s{35.70} \.{\land} messages \.{=} EmptyBag}%
390 | \@x{\@s{35.70} \.{\land} InitSenderVars}%
391 | \@x{\@s{35.70} \.{\land} InitConnectorVars}%
392 | \@x{\@s{35.70} \.{\land} InitLedgerVars}%
393 | \@pvspace{8.0pt}%
394 | \@x{}\midbar\@xx{}%
395 | \@x{}%
396 | \@y{\@s{0}%
397 | Define state transitions
398 | }%
399 | \@xx{}%
400 | \@pvspace{8.0pt}%
401 | \@x{}%
402 | \@y{\@s{0}%
403 | Participant \ensuremath{i} proposes all the subpayments
404 | }%
405 | \@xx{}%
406 | \@x{ StartProposalPhase ( i ) \.{\defeq}}%
407 | \@x{\@s{16.4} \.{\land} senderState \.{=} S\_Ready}%
408 | \@x{\@s{16.4} \.{\land} senderState \.{'} \.{=} S\_ProposalWaiting}%
409 | \@x{\@s{16.4} \.{\land} Broadcast ( \{ [}%
410 | \@x{\@s{35.71} mtype\@s{13.68} \.{\mapsto} SubpaymentProposalRequest ,\,}%
411 | \@x{\@s{35.71} msource\@s{4.1} \.{\mapsto} i ,\,}%
412 | \@x{\@s{35.71} mdest\@s{13.74} \.{\mapsto} k}%
413 | \@x{\@s{27.51} ] \.{:} k \.{\in} Connector \} )}%
414 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} ledgerVars ,\, connectorVars
415 | ,\, senderProposalResponses {\rangle}}%
416 | \@pvspace{8.0pt}%
417 | \@x{}%
418 | \@y{\@s{0}%
419 | Participant \ensuremath{i} starts off the preparation chain
420 | }%
421 | \@xx{}%
422 | \@x{ StartPreparationPhase ( i ) \.{\defeq}}%
423 | \@x{\@s{16.4} \.{\land} senderState \.{=} S\_ProposalWaiting}%
424 | \@x{\@s{16.4} \.{\land} \E\, p \.{\in} {\DOMAIN} senderProposalResponses
425 | \.{:} senderProposalResponses [ p ]}%
426 | \@x{\@s{16.4} \.{\land} senderState \.{'} \.{=} S\_Waiting}%
427 | \@x{\@s{16.4} \.{\land} Send ( [ mtype\@s{9.58} \.{\mapsto} PrepareRequest
428 | ,\,}%
429 | \@x{\@s{56.16} msource \.{\mapsto} i ,\,}%
430 | \@x{\@s{56.16} mdest\@s{9.64} \.{\mapsto} i \.{+} 1 ] )}%
431 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} ledgerVars ,\, connectorVars
432 | ,\, senderProposalResponses {\rangle}}%
433 | \@pvspace{8.0pt}%
434 | \@x{}%
435 | \@y{\@s{0}%
436 | Ledger spontaneously aborts
437 | }%
438 | \@xx{}%
439 | \@x{ LedgerAbort ( l ) \.{\defeq}}%
440 | \@x{\@s{16.4} \.{\land} ledgerState [ l ] \.{=} L\_Proposed}%
441 | \@x{\@s{16.4} \.{\land} ledgerState \.{'} \.{=} [ ledgerState {\EXCEPT}
442 | {\bang} [ l ] \.{=} L\_Aborted ]}%
443 | \@x{\@s{16.4} \.{\land} Send ( [ mtype\@s{9.58} \.{\mapsto} AbortNotify ,\,}%
444 | \@x{\@s{56.16} msource \.{\mapsto} l ,\,}%
445 | \@x{\@s{56.16} mdest\@s{9.64} \.{\mapsto} l \.{-} 1 ] )}%
446 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
447 | ,\, ledgerExpiration {\rangle}}%
448 | \@pvspace{8.0pt}%
449 | \@x{}%
450 | \@y{\@s{0}%
451 | Transfer times out
452 | }%
453 | \@xx{}%
454 | \@x{ LedgerTimeout ( l ) \.{\defeq}}%
455 | \@x{\@s{16.4} \.{\land} {\lnot} IsFinalLedgerState ( ledgerState [ l ] )}%
456 | \@x{\@s{16.4} \.{\land} ledgerExpiration [ l ] \.{\leq} clock}%
457 | \@x{\@s{16.4} \.{\land} ledgerState \.{'} \.{=} [ ledgerState {\EXCEPT}
458 | {\bang} [ l ] \.{=} L\_Aborted ]}%
459 | \@x{\@s{16.4} \.{\land} Send ( [ mtype\@s{9.58} \.{\mapsto} AbortNotify ,\,}%
460 | \@x{\@s{56.16} msource \.{\mapsto} l ,\,}%
461 | \@x{\@s{56.16} mdest\@s{9.64} \.{\mapsto} l \.{-} 1 ] )}%
462 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
463 | ,\, ledgerExpiration {\rangle}}%
464 | \@pvspace{8.0pt}%
465 | \@x{}%
466 | \@y{\@s{0}%
467 | If no messages are in flight and the sender isn\mbox{'}t doing anything,
468 | advance the
469 | }%
470 | \@xx{}%
471 | \@x{}%
472 | \@y{\@s{0}%
473 | clock
474 | }%
475 | \@xx{}%
476 | \@x{ NothingHappens \.{\defeq}}%
477 | \@x{\@s{16.4} \.{\land} clock \.{\leq} Max ( \{ ledgerExpiration [ x ] \.{:}
478 | x \.{\in} Ledger \} )}%
479 | \@x{\@s{16.4} \.{\land} BagCardinality ( messages ) \.{=} 0}%
480 | \@x{\@s{16.4} \.{\land} senderState \.{\neq} S\_Ready}%
481 | \@x{\@s{16.4} \.{\land} \.{\lor} senderState \.{\neq} S\_ProposalWaiting}%
482 | \@x{\@s{27.51} \.{\lor} \A\, p \.{\in} {\DOMAIN} senderProposalResponses
483 | \.{:} {\lnot} senderProposalResponses [ p ]}%
484 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} messages ,\, senderVars ,\,
485 | connectorVars ,\, ledgerVars {\rangle}}%
486 | \@pvspace{8.0pt}%
487 | \@x{}\midbar\@xx{}%
488 | \@x{}%
489 | \@y{\@s{0}%
490 | Message handlers
491 | }%
492 | \@xx{}%
493 | \@x{}%
494 | \@y{\@s{0}%
495 | \ensuremath{i \.{=}} recipient, \ensuremath{j \.{=}} sender, \ensuremath{m
496 | \.{=}} message
497 | }%
498 | \@xx{}%
499 | \@pvspace{8.0pt}%
500 | \@x{}%
501 | \@y{\@s{0}%
502 | Ledger \ensuremath{i} receives a Prepare request from participant
503 | \ensuremath{j
504 | }}%
505 | \@xx{}%
506 | \@x{ LedgerHandlePrepareRequest ( i ,\, j ,\, m ) \.{\defeq}}%
507 | \@x{\@s{16.4} \.{\LET} valid \.{\defeq} \.{\land} ledgerState [ i ] \.{=}
508 | L\_Proposed}%
509 | \@x{\@s{77.16} \.{\land} j \.{=} i \.{-} 1}%
510 | \@x{\@s{16.4} \.{\IN} \.{\lor} \.{\land} valid}%
511 | \@x{\@s{47.91} \.{\land} i \.{\in} Ledger}%
512 | \@x{\@s{47.91} \.{\land} ledgerState \.{'} \.{=} [ ledgerState {\EXCEPT}
513 | {\bang} [ i ] \.{=} L\_Prepared ]}%
514 | \@x{\@s{47.91} \.{\land} Reply ( [ mtype\@s{9.58} \.{\mapsto} PrepareNotify
515 | ,\,}%
516 | \@x{\@s{90.47} msource \.{\mapsto} i ,\,}%
517 | \@x{\@s{90.47} mdest\@s{9.64} \.{\mapsto} i \.{+} 1 ] ,\, m )}%
518 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
519 | ,\, ledgerExpiration {\rangle}}%
520 | \@x{\@s{36.79} \.{\lor} \.{\land} {\lnot} valid}%
521 | \@x{\@s{47.91} \.{\land} i \.{\in} Ledger}%
522 | \@x{\@s{47.91} \.{\land} Discard ( m )}%
523 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
524 | ,\, ledgerVars {\rangle}}%
525 | \@pvspace{8.0pt}%
526 | \@x{}%
527 | \@y{\@s{0}%
528 | Ledger \ensuremath{i} receives an Execute request from process \ensuremath{j
529 | }}%
530 | \@xx{}%
531 | \@x{ LedgerHandleExecuteRequest ( i ,\, j ,\, m ) \.{\defeq}}%
532 | \@x{\@s{16.4} \.{\LET} valid \.{\defeq} \.{\land} ledgerState [ i ] \.{=}
533 | L\_Prepared}%
534 | \@x{\@s{77.16} \.{\land} ledgerExpiration [ i ] \.{>} clock}%
535 | \@x{\@s{77.16} \.{\land} m . mreceipt \.{=} R\_ReceiptSignature}%
536 | \@x{\@s{16.4} \.{\IN} \.{\lor} \.{\land} valid}%
537 | \@x{\@s{47.91} \.{\land} ledgerState \.{'} \.{=} [ ledgerState {\EXCEPT}
538 | {\bang} [ i ] \.{=} L\_Executed ]}%
539 | \@x{\@s{47.91} \.{\land} Reply ( [ mtype\@s{12.29} \.{\mapsto} ExecuteNotify
540 | ,\,}%
541 | \@x{\@s{90.47} msource\@s{2.71} \.{\mapsto} i ,\,}%
542 | \@x{\@s{90.47} mdest\@s{12.35} \.{\mapsto} i \.{-} 1 ,\,}%
543 | \@x{\@s{90.47} mreceipt\@s{1.49} \.{\mapsto} m . mreceipt ] ,\, m )}%
544 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
545 | ,\, ledgerExpiration {\rangle}}%
546 | \@x{\@s{36.79} \.{\lor} \.{\land} {\lnot} valid}%
547 | \@x{\@s{47.91} \.{\land} Discard ( m )}%
548 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
549 | ,\, ledgerVars {\rangle}}%
550 | \@pvspace{8.0pt}%
551 | \@x{}%
552 | \@y{\@s{0}%
553 | Ledger \ensuremath{i} receives a message
554 | }%
555 | \@xx{}%
556 | \@x{ LedgerReceive ( i ,\, j ,\, m ) \.{\defeq}}%
557 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} PrepareRequest}%
558 | \@x{\@s{27.51} \.{\land} LedgerHandlePrepareRequest ( i ,\, j ,\, m )}%
559 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} ExecuteRequest}%
560 | \@x{\@s{27.51} \.{\land} LedgerHandleExecuteRequest ( i ,\, j ,\, m )}%
561 | \@pvspace{8.0pt}%
562 | \@x{}%
563 | \@y{\@s{0}%
564 | Sender receives a \ensuremath{SubpaymentProposal} request
565 | }%
566 | \@xx{}%
567 | \@x{ SenderHandleSubpaymentProposalResponse ( i ,\, j ,\, m ) \.{\defeq}}%
568 | \@x{\@s{16.4} \.{\land} i \.{=} Sender}%
569 | \@x{\@s{16.4} \.{\land} senderProposalResponses \.{'} \.{=} [
570 | senderProposalResponses {\EXCEPT} {\bang} [ j ] \.{=} {\TRUE} ]}%
571 | \@x{\@s{16.4} \.{\land} Discard ( m )}%
572 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} connectorVars ,\, ledgerVars
573 | ,\, senderState {\rangle}}%
574 | \@pvspace{8.0pt}%
575 | \@x{}%
576 | \@y{\@s{0}%
577 | Ledger \ensuremath{j} notifies sender that the transfer is executed
578 | }%
579 | \@xx{}%
580 | \@x{ SenderHandleExecuteNotify ( i ,\, j ,\, m ) \.{\defeq}}%
581 | \@x{\@s{16.4} \.{\lor} \.{\land} senderState \.{=} S\_Waiting}%
582 | \@x{\@s{27.51} \.{\land} senderState \.{'} \.{=} S\_Done}%
583 | \@x{\@s{27.51} \.{\land} Discard ( m )}%
584 | \@x{\@s{27.51} \.{\land} {\UNCHANGED} {\langle} ledgerVars ,\, connectorVars
585 | ,\, senderProposalResponses {\rangle}}%
586 | \@x{\@s{16.4} \.{\lor} \.{\land} senderState \.{\neq} S\_Waiting}%
587 | \@x{\@s{27.51} \.{\land} Discard ( m )}%
588 | \@x{\@s{27.51} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
589 | ,\, ledgerVars {\rangle}}%
590 | \@pvspace{8.0pt}%
591 | \@x{}%
592 | \@y{\@s{0}%
593 | Ledger \ensuremath{j} notifies sender that the transfer is aborted
594 | }%
595 | \@xx{}%
596 | \@x{ SenderHandleAbortNotify ( i ,\, j ,\, m ) \.{\defeq}}%
597 | \@x{\@s{16.4} \.{\LET} isSenderWaiting \.{\defeq} senderState \.{\in} \{
598 | S\_ProposalWaiting ,\, S\_Waiting ,\, S\_Ready \}}%
599 | \@x{\@s{16.4} \.{\IN} \.{\lor} \.{\land} isSenderWaiting}%
600 | \@x{\@s{47.91} \.{\land} senderState \.{'} \.{=} S\_Done}%
601 | \@x{\@s{47.91} \.{\land} Discard ( m )}%
602 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} ledgerVars ,\, connectorVars
603 | ,\, senderProposalResponses {\rangle}}%
604 | \@x{\@s{36.79} \.{\lor} \.{\land} {\lnot} isSenderWaiting}%
605 | \@x{\@s{47.91} \.{\land} Discard ( m )}%
606 | \@x{\@s{47.91} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
607 | ,\, ledgerVars {\rangle}}%
608 | \@pvspace{8.0pt}%
609 | \@x{}%
610 | \@y{\@s{0}%
611 | Sender receives a message
612 | }%
613 | \@xx{}%
614 | \@x{ SenderReceive ( i ,\, j ,\, m ) \.{\defeq}}%
615 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} SubpaymentProposalResponse}%
616 | \@x{\@s{27.51} \.{\land} SenderHandleSubpaymentProposalResponse ( i ,\, j ,\,
617 | m )}%
618 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} ExecuteNotify}%
619 | \@x{\@s{27.51} \.{\land} SenderHandleExecuteNotify ( i ,\, j ,\, m )}%
620 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} AbortNotify}%
621 | \@x{\@s{27.51} \.{\land} SenderHandleAbortNotify ( i ,\, j ,\, m )}%
622 | \@pvspace{8.0pt}%
623 | \@x{}%
624 | \@y{\@s{0}%
625 | Ledger \ensuremath{j} notifies recipient that the transfer is prepared
626 | }%
627 | \@xx{}%
628 | \@x{ RecipientHandlePrepareNotify ( i ,\, j ,\, m ) \.{\defeq}}%
629 | \@x{\@s{16.4} \.{\lor} \.{\land} Reply ( [ mtype\@s{12.29} \.{\mapsto}
630 | ExecuteRequest ,\,}%
631 | \@x{\@s{70.07} msource\@s{2.71} \.{\mapsto} i ,\,}%
632 | \@x{\@s{70.07} mdest\@s{12.35} \.{\mapsto} i \.{-} 1 ,\,}%
633 | \@x{\@s{70.07} mreceipt\@s{1.49} \.{\mapsto} R\_ReceiptSignature ] ,\, m )}%
634 | \@x{\@s{27.51} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
635 | ,\, ledgerVars {\rangle}}%
636 | \@pvspace{8.0pt}%
637 | \@x{}%
638 | \@y{\@s{0}%
639 | Recipient receives a message
640 | }%
641 | \@xx{}%
642 | \@x{ RecipientReceive ( i ,\, j ,\, m ) \.{\defeq}}%
643 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} PrepareNotify}%
644 | \@x{\@s{27.51} \.{\land} RecipientHandlePrepareNotify ( i ,\, j ,\, m )}%
645 | \@pvspace{8.0pt}%
646 | \@x{}%
647 | \@y{\@s{0}%
648 | Connector \ensuremath{i} receives a \ensuremath{SubpaymentProposal} request
649 | }%
650 | \@xx{}%
651 | \@x{ ConnectorHandleSubpaymentProposalRequest ( i ,\, j ,\, m ) \.{\defeq}}%
652 | \@x{\@s{16.4} \.{\land} connectorState \.{'} \.{=} [ connectorState {\EXCEPT}
653 | {\bang} [ i ] \.{=} C\_Proposed ]}%
654 | \@x{\@s{16.4} \.{\land} Reply ( [ mtype\@s{13.68} \.{\mapsto}
655 | SubpaymentProposalResponse ,\,}%
656 | \@x{\@s{58.96} msource\@s{4.1} \.{\mapsto} i ,\,}%
657 | \@x{\@s{58.96} mdest\@s{13.74} \.{\mapsto} j ] ,\, m )}%
658 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, ledgerVars
659 | {\rangle}}%
660 | \@pvspace{8.0pt}%
661 | \@x{}%
662 | \@y{\@s{0}%
663 | Ledger \ensuremath{j} notifies connector \ensuremath{i} that the transfer is
664 | prepared
665 | }%
666 | \@xx{}%
667 | \@x{ ConnectorHandlePrepareNotify ( i ,\, j ,\, m ) \.{\defeq}}%
668 | \@x{\@s{16.4} \.{\lor} \.{\land} Reply ( [ mtype\@s{9.58} \.{\mapsto}
669 | PrepareRequest ,\,}%
670 | \@x{\@s{70.07} msource \.{\mapsto} i ,\,}%
671 | \@x{\@s{70.07} mdest\@s{9.64} \.{\mapsto} i \.{+} 1 ] ,\, m )}%
672 | \@x{\@s{27.51} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
673 | ,\, ledgerVars {\rangle}}%
674 | \@pvspace{8.0pt}%
675 | \@x{}%
676 | \@y{\@s{0}%
677 | Ledger \ensuremath{j} notifies connector \ensuremath{i} that the transfer is
678 | executed
679 | }%
680 | \@xx{}%
681 | \@x{ ConnectorHandleExecuteNotify ( i ,\, j ,\, m ) \.{\defeq}}%
682 | \@x{\@s{16.4} \.{\land} Reply ( [ mtype\@s{12.29} \.{\mapsto} ExecuteRequest
683 | ,\,}%
684 | \@x{\@s{58.96} msource\@s{2.71} \.{\mapsto} i ,\,}%
685 | \@x{\@s{58.96} mdest\@s{12.35} \.{\mapsto} i \.{-} 1 ,\,}%
686 | \@x{\@s{58.96} mreceipt\@s{1.49} \.{\mapsto} m . mreceipt ] ,\, m )}%
687 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
688 | ,\, ledgerVars {\rangle}}%
689 | \@pvspace{8.0pt}%
690 | \@x{}%
691 | \@y{\@s{0}%
692 | Ledger \ensuremath{j} notifies connector \ensuremath{i} that the transfer is
693 | aborted
694 | }%
695 | \@xx{}%
696 | \@x{ ConnectorHandleAbortNotify ( i ,\, j ,\, m ) \.{\defeq}}%
697 | \@x{\@s{16.4} \.{\land} Discard ( m )}%
698 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} {\langle} senderVars ,\, connectorVars
699 | ,\, ledgerVars {\rangle}}%
700 | \@pvspace{8.0pt}%
701 | \@x{}%
702 | \@y{\@s{0}%
703 | Connector receives a message
704 | }%
705 | \@xx{}%
706 | \@x{ ConnectorReceive ( i ,\, j ,\, m ) \.{\defeq}}%
707 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} SubpaymentProposalRequest}%
708 | \@x{\@s{27.51} \.{\land} ConnectorHandleSubpaymentProposalRequest ( i ,\, j
709 | ,\, m )}%
710 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} PrepareNotify}%
711 | \@x{\@s{27.51} \.{\land} ConnectorHandlePrepareNotify ( i ,\, j ,\, m )}%
712 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} ExecuteNotify}%
713 | \@x{\@s{27.51} \.{\land} ConnectorHandleExecuteNotify ( i ,\, j ,\, m )}%
714 | \@x{\@s{16.4} \.{\lor} \.{\land} m . mtype \.{=} AbortNotify}%
715 | \@x{\@s{27.51} \.{\land} ConnectorHandleAbortNotify ( i ,\, j ,\, m )}%
716 | \@pvspace{8.0pt}%
717 | \@x{}%
718 | \@y{\@s{0}%
719 | Receive a message
720 | }%
721 | \@xx{}%
722 | \@x{ Receive ( m ) \.{\defeq}}%
723 | \@x{\@s{16.4} \.{\LET} i\@s{0.42} \.{\defeq} m . mdest}%
724 | \@x{\@s{36.79} j \.{\defeq} m . msource}%
725 | \@x{\@s{16.4} \.{\IN} \.{\lor} \.{\land} i \.{\in} Ledger}%
726 | \@x{\@s{47.91} \.{\land} LedgerReceive ( i ,\, j ,\, m )}%
727 | \@x{\@s{36.79} \.{\lor} \.{\land} i \.{=} Sender}%
728 | \@x{\@s{47.91} \.{\land} SenderReceive ( i ,\, j ,\, m )}%
729 | \@x{\@s{36.79} \.{\lor} \.{\land} i \.{=} Recipient}%
730 | \@x{\@s{47.91} \.{\land} RecipientReceive ( i ,\, j ,\, m )}%
731 | \@x{\@s{36.79} \.{\lor} \.{\land} i \.{\in} Connector}%
732 | \@x{\@s{47.91} \.{\land} ConnectorReceive ( i ,\, j ,\, m )}%
733 | \@pvspace{8.0pt}%
734 | \@x{}%
735 | \@y{\@s{0}%
736 | End of message handlers
737 | }%
738 | \@xx{}%
739 | \@x{}\midbar\@xx{}%
740 | \@x{}%
741 | \@y{\@s{0}%
742 | Defines how the variables may transition
743 | }%
744 | \@xx{}%
745 | \@pvspace{8.0pt}%
746 | \@x{ Termination \.{\defeq}}%
747 | \@x{\@s{16.4} \.{\land} \A\, l \.{\in} Ledger \.{:} IsFinalLedgerState (
748 | ledgerState [ l ] )}%
749 | \@x{\@s{16.4} \.{\land} senderState \.{=} S\_Done}%
750 | \@x{\@s{16.4} \.{\land} {\UNCHANGED} vars}%
751 | \@pvspace{8.0pt}%
752 | \@x{ Next \.{\defeq} \.{\lor} \.{\land} \.{\lor} StartProposalPhase ( Sender
753 | )}%
754 | \@x{\@s{62.05} \.{\lor} StartPreparationPhase ( Sender )}%
755 | \@x{\@s{62.05} \.{\lor} \E\, l\@s{5.35} \.{\in} Ledger \.{:} LedgerAbort ( l
756 | )}%
757 | \@x{\@s{62.05} \.{\lor} \E\, l\@s{5.35} \.{\in} Ledger \.{:} LedgerTimeout (
758 | l )}%
759 | \@x{\@s{62.05} \.{\lor} \E\, m \.{\in} {\DOMAIN} messages \.{:} Receive ( m
760 | )}%
761 | \@x{\@s{62.05} \.{\lor} NothingHappens}%
762 | \@x{\@s{50.94} \.{\land} clock \.{'} \.{=} clock \.{+} 1}%
763 | \@x{\@s{39.83} \.{\lor} Termination}%
764 | \@pvspace{8.0pt}%
765 | \@x{}%
766 | \@y{\@s{0}%
767 | The specification must start with the initial state and transition according
768 | }%
769 | \@xx{}%
770 | \@x{}%
771 | \@y{\@s{0}%
772 | to \ensuremath{Next}.
773 | }%
774 | \@xx{}%
775 | \@x{ Spec \.{\defeq} Init \.{\land} {\Box} [ Next ]_{ vars}}%
776 | \@pvspace{8.0pt}%
777 | \@x{}\bottombar\@xx{}%
778 | \end{document}
--------------------------------------------------------------------------------
/acm.bst:
--------------------------------------------------------------------------------
1 | % Copyright (C) 1986, 1988, 2010 Howard Trickey and Oren Patashnik.
2 | % Unlimited copying and redistribution of this file are permitted as long as
3 | % it is unmodified. Modifications (and redistribution of modified versions)
4 | % are also permitted, but only if the resulting file is renamed.
5 | %
6 | % ACM Transactions bibliography style (8-Dec-10 version)
7 | % A lot like abbrv.bst, but names come out "Last, initials", and in \sc.
8 | % Some dates are parenthesized.
9 | %
10 | % History
11 | % 2/ 6/86 (HWT) Original version, by Howard Trickey.
12 | % 3/ 5/86 (HWT) Put in pp. everywhere but articles, as per ACM style.
13 | % 1/24/88 (OP&HWT) Updated for BibTeX version 0.99a, Oren Patashnik;
14 | % corrected the abbreviations to "Mar." and "Sept.";
15 | % THIS `acm' VERSION DOES NOT WORK WITH BIBTEX 0.98i.
16 | % 12/ 8/10 (OP&HWT) Clarify license.
17 |
18 | ENTRY
19 | { address
20 | author
21 | booktitle
22 | chapter
23 | edition
24 | editor
25 | howpublished
26 | institution
27 | journal
28 | key
29 | month
30 | note
31 | number
32 | organization
33 | pages
34 | publisher
35 | school
36 | series
37 | title
38 | type
39 | volume
40 | year
41 | }
42 | {}
43 | { label }
44 |
45 | INTEGERS { output.state before.all mid.sentence after.sentence after.block }
46 |
47 | FUNCTION {init.state.consts}
48 | { #0 'before.all :=
49 | #1 'mid.sentence :=
50 | #2 'after.sentence :=
51 | #3 'after.block :=
52 | }
53 |
54 | STRINGS { s t }
55 |
56 | FUNCTION {output.nonnull}
57 | { 's :=
58 | output.state mid.sentence =
59 | { ", " * write$ }
60 | { output.state after.block =
61 | { add.period$ write$
62 | newline$
63 | "\newblock " write$
64 | }
65 | { output.state before.all =
66 | 'write$
67 | { add.period$ " " * write$ }
68 | if$
69 | }
70 | if$
71 | mid.sentence 'output.state :=
72 | }
73 | if$
74 | s
75 | }
76 |
77 | FUNCTION {output}
78 | { duplicate$ empty$
79 | 'pop$
80 | 'output.nonnull
81 | if$
82 | }
83 |
84 | FUNCTION {output.check}
85 | { 't :=
86 | duplicate$ empty$
87 | { pop$ "empty " t * " in " * cite$ * warning$ }
88 | 'output.nonnull
89 | if$
90 | }
91 |
92 | FUNCTION {output.bibitem}
93 | { newline$
94 | "\bibitem{" write$
95 | cite$ write$
96 | "}" write$
97 | newline$
98 | ""
99 | before.all 'output.state :=
100 | }
101 |
102 | FUNCTION {fin.entry}
103 | { add.period$
104 | write$
105 | newline$
106 | }
107 |
108 | FUNCTION {new.block}
109 | { output.state before.all =
110 | 'skip$
111 | { after.block 'output.state := }
112 | if$
113 | }
114 |
115 | FUNCTION {new.sentence}
116 | { output.state after.block =
117 | 'skip$
118 | { output.state before.all =
119 | 'skip$
120 | { after.sentence 'output.state := }
121 | if$
122 | }
123 | if$
124 | }
125 |
126 | FUNCTION {not}
127 | { { #0 }
128 | { #1 }
129 | if$
130 | }
131 |
132 | FUNCTION {and}
133 | { 'skip$
134 | { pop$ #0 }
135 | if$
136 | }
137 |
138 | FUNCTION {or}
139 | { { pop$ #1 }
140 | 'skip$
141 | if$
142 | }
143 |
144 | FUNCTION {new.block.checka}
145 | { empty$
146 | 'skip$
147 | 'new.block
148 | if$
149 | }
150 |
151 | FUNCTION {new.block.checkb}
152 | { empty$
153 | swap$ empty$
154 | and
155 | 'skip$
156 | 'new.block
157 | if$
158 | }
159 |
160 | FUNCTION {field.or.null}
161 | { duplicate$ empty$
162 | { pop$ "" }
163 | 'skip$
164 | if$
165 | }
166 |
167 | FUNCTION {emphasize}
168 | { duplicate$ empty$
169 | { pop$ "" }
170 | { "{\em " swap$ * "}" * }
171 | if$
172 | }
173 |
174 | FUNCTION {emphasizeic}
175 | { duplicate$ empty$
176 | { pop$ "" }
177 | { "{\em " swap$ * "\/}" * }
178 | if$
179 | }
180 |
181 | FUNCTION {scapify}
182 | { duplicate$ empty$
183 | { pop$ "" }
184 | { "{\sc " swap$ * "}" * }
185 | if$
186 | }
187 |
188 | INTEGERS { nameptr namesleft numnames }
189 |
190 | FUNCTION {format.names}
191 | { 's :=
192 | #1 'nameptr :=
193 | s num.names$ 'numnames :=
194 | numnames 'namesleft :=
195 | { namesleft #0 > }
196 | { s nameptr "{vv~}{ll}{, jj}{, f.}" format.name$ 't :=
197 | nameptr #1 >
198 | { namesleft #1 >
199 | { ", " * t * }
200 | { t "others" =
201 | { ", et~al." * }
202 | { ", and " * t * }
203 | if$
204 | }
205 | if$
206 | }
207 | 't
208 | if$
209 | nameptr #1 + 'nameptr :=
210 | namesleft #1 - 'namesleft :=
211 | }
212 | while$
213 | }
214 |
215 | % For names inside entries (e.g., editors of an "In ...");
216 | % this is exactly ABBRV.BST's `format.names' function.
217 | FUNCTION {format.innames}
218 | { 's :=
219 | #1 'nameptr :=
220 | s num.names$ 'numnames :=
221 | numnames 'namesleft :=
222 | { namesleft #0 > }
223 | { s nameptr "{f.~}{vv~}{ll}{, jj}" format.name$ 't :=
224 | nameptr #1 >
225 | { namesleft #1 >
226 | { ", " * t * }
227 | { numnames #2 >
228 | { "," * }
229 | 'skip$
230 | if$
231 | t "others" =
232 | { " et~al." * }
233 | { " and " * t * }
234 | if$
235 | }
236 | if$
237 | }
238 | 't
239 | if$
240 | nameptr #1 + 'nameptr :=
241 | namesleft #1 - 'namesleft :=
242 | }
243 | while$
244 | }
245 |
246 | FUNCTION {format.authors}
247 | { author empty$
248 | { "" }
249 | { author format.names scapify }
250 | if$
251 | }
252 |
253 | FUNCTION {format.editors}
254 | { editor empty$
255 | { "" }
256 | { editor format.names scapify
257 | editor num.names$ #1 >
258 | { ", Eds." * }
259 | { ", Ed." * }
260 | if$
261 | }
262 | if$
263 | }
264 |
265 | FUNCTION {format.ineditors}
266 | { editor empty$
267 | { "" }
268 | { editor format.innames
269 | editor num.names$ #1 >
270 | { ", Eds." * }
271 | { ", Ed." * }
272 | if$
273 | }
274 | if$
275 | }
276 |
277 | FUNCTION {format.title}
278 | { title empty$
279 | { "" }
280 | { title "t" change.case$ }
281 | if$
282 | }
283 |
284 | FUNCTION {n.dashify}
285 | { 't :=
286 | ""
287 | { t empty$ not }
288 | { t #1 #1 substring$ "-" =
289 | { t #1 #2 substring$ "--" = not
290 | { "--" *
291 | t #2 global.max$ substring$ 't :=
292 | }
293 | { { t #1 #1 substring$ "-" = }
294 | { "-" *
295 | t #2 global.max$ substring$ 't :=
296 | }
297 | while$
298 | }
299 | if$
300 | }
301 | { t #1 #1 substring$ *
302 | t #2 global.max$ substring$ 't :=
303 | }
304 | if$
305 | }
306 | while$
307 | }
308 |
309 | FUNCTION {format.date}
310 | { year empty$
311 | { month empty$
312 | { "" }
313 | { "there's a month but no year in " cite$ * warning$
314 | month
315 | }
316 | if$
317 | }
318 | { month empty$
319 | 'year
320 | { month " " * year * }
321 | if$
322 | }
323 | if$
324 | }
325 |
326 | FUNCTION {format.btitle}
327 | { title emphasize
328 | }
329 |
330 | FUNCTION {tie.or.space.connect}
331 | { duplicate$ text.length$ #3 <
332 | { "~" }
333 | { " " }
334 | if$
335 | swap$ * *
336 | }
337 |
338 | FUNCTION {either.or.check}
339 | { empty$
340 | 'pop$
341 | { "can't use both " swap$ * " fields in " * cite$ * warning$ }
342 | if$
343 | }
344 |
345 | FUNCTION {format.bvolume}
346 | { volume empty$
347 | { "" }
348 | { "vol.~" volume *
349 | series empty$
350 | 'skip$
351 | { " of " * series emphasize * }
352 | if$
353 | "volume and number" number either.or.check
354 | }
355 | if$
356 | }
357 |
358 | FUNCTION {format.number.series}
359 | { volume empty$
360 | { number empty$
361 | { series field.or.null }
362 | { output.state mid.sentence =
363 | { "no.~" }
364 | { "No.~" }
365 | if$
366 | number *
367 | series empty$
368 | { "there's a number but no series in " cite$ * warning$ }
369 | { " in " * series * }
370 | if$
371 | }
372 | if$
373 | }
374 | { "" }
375 | if$
376 | }
377 |
378 | FUNCTION {format.edition}
379 | { edition empty$
380 | { "" }
381 | { output.state mid.sentence =
382 | { edition "l" change.case$ "~ed." * }
383 | { edition "t" change.case$ "~ed." * }
384 | if$
385 | }
386 | if$
387 | }
388 |
389 | FUNCTION {format.pages}
390 | { pages empty$
391 | { "" }
392 | { pages n.dashify }
393 | if$
394 | }
395 |
396 | INTEGERS { multiresult }
397 |
398 | FUNCTION {multi.page.check}
399 | { 't :=
400 | #0 'multiresult :=
401 | { multiresult not
402 | t empty$ not
403 | and
404 | }
405 | { t #1 #1 substring$
406 | duplicate$ "-" =
407 | swap$ duplicate$ "," =
408 | swap$ "+" =
409 | or or
410 | { #1 'multiresult := }
411 | { t #2 global.max$ substring$ 't := }
412 | if$
413 | }
414 | while$
415 | multiresult
416 | }
417 |
418 | FUNCTION {format.pp.pages}
419 | { pages empty$
420 | { "" }
421 | { pages multi.page.check
422 | { "pp.~" pages n.dashify * }
423 | { "p.~" pages * }
424 | if$
425 | }
426 | if$
427 | }
428 |
429 | FUNCTION {format.journal.vol.num.date}
430 | { journal empty$
431 | { "empty journal in " cite$ * warning$
432 | ""
433 | }
434 | { journal
435 | volume empty$
436 | 'skip$
437 | { " " * volume * }
438 | if$
439 | number empty$
440 | 'emphasizeic
441 | { emphasize ", " * number * }
442 | if$
443 | year empty$
444 | { "empty year in " cite$ * warning$ }
445 | { " (" * format.date * ")" * }
446 | if$
447 | }
448 | if$
449 | }
450 |
451 | FUNCTION {format.chapter.pages}
452 | { chapter empty$
453 | 'format.pp.pages
454 | { type empty$
455 | { "ch.~" chapter * }
456 | { type "l" change.case$ chapter tie.or.space.connect }
457 | if$
458 | pages empty$
459 | 'skip$
460 | { ", " * format.pp.pages * }
461 | if$
462 | }
463 | if$
464 | }
465 |
466 | FUNCTION {format.in.ed.booktitle}
467 | { booktitle empty$
468 | { "" }
469 | { "In " booktitle emphasize *
470 | editor empty$
471 | 'skip$
472 | { ", " * format.ineditors * }
473 | if$
474 | }
475 | if$
476 | }
477 |
478 | % The proceedings title (it's on the stack) gets an (address, date) appended
479 | FUNCTION {format.proc.date}
480 | { duplicate$ empty$
481 | { pop$ "" }
482 | { year empty$
483 | { "empty year in " cite$ * warning$
484 | address empty$
485 | 'emphasize
486 | { emphasizeic
487 | " (" * address * ")" *
488 | }
489 | if$
490 | }
491 | { emphasizeic
492 | " (" *
493 | address empty$
494 | 'skip$
495 | { address * ", " * }
496 | if$
497 | format.date *
498 | ")" *
499 | }
500 | if$
501 | }
502 | if$
503 | }
504 |
505 | FUNCTION {format.in.proc.date}
506 | { booktitle empty$
507 | { "" }
508 | { "In " booktitle format.proc.date * }
509 | if$
510 | }
511 |
512 | FUNCTION {empty.misc.check}
513 | { author empty$ title empty$ howpublished empty$
514 | month empty$ year empty$ note empty$
515 | and and and and and
516 | key empty$ not and
517 | { "all relevant fields are empty in " cite$ * warning$ }
518 | 'skip$
519 | if$
520 | }
521 |
522 | FUNCTION {format.thesis.type}
523 | { type empty$
524 | 'skip$
525 | { pop$
526 | type "t" change.case$
527 | }
528 | if$
529 | }
530 |
531 | FUNCTION {format.tr.number}
532 | { type empty$
533 | { "Tech. Rep." }
534 | 'type
535 | if$
536 | number empty$
537 | { "t" change.case$ }
538 | { number tie.or.space.connect }
539 | if$
540 | }
541 |
542 | FUNCTION {format.article.crossref}
543 | { key empty$
544 | { journal empty$
545 | { "need key or journal for " cite$ * " to crossref " * crossref *
546 | warning$
547 | ""
548 | }
549 | { "In {\em " journal * "\/}" * }
550 | if$
551 | }
552 | { "In " key * }
553 | if$
554 | " \cite{" * crossref * "}" *
555 | }
556 |
557 | FUNCTION {format.crossref.editor}
558 | { editor #1 "{vv~}{ll}" format.name$
559 | editor num.names$ duplicate$
560 | #2 >
561 | { pop$ " et~al." * }
562 | { #2 <
563 | 'skip$
564 | { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" =
565 | { " et~al." * }
566 | { " and " * editor #2 "{vv~}{ll}" format.name$ * }
567 | if$
568 | }
569 | if$
570 | }
571 | if$
572 | }
573 |
574 | FUNCTION {format.book.crossref}
575 | { volume empty$
576 | { "empty volume in " cite$ * "'s crossref of " * crossref * warning$
577 | "In "
578 | }
579 | { "Vol.~" volume *
580 | " of " *
581 | }
582 | if$
583 | editor empty$
584 | editor field.or.null author field.or.null =
585 | or
586 | { key empty$
587 | { series empty$
588 | { "need editor, key, or series for " cite$ * " to crossref " *
589 | crossref * warning$
590 | "" *
591 | }
592 | { "{\em " * series * "\/}" * }
593 | if$
594 | }
595 | { key * }
596 | if$
597 | }
598 | { format.crossref.editor * }
599 | if$
600 | " \cite{" * crossref * "}" *
601 | }
602 |
603 | FUNCTION {format.incoll.inproc.crossref}
604 | { editor empty$
605 | editor field.or.null author field.or.null =
606 | or
607 | { key empty$
608 | { booktitle empty$
609 | { "need editor, key, or booktitle for " cite$ * " to crossref " *
610 | crossref * warning$
611 | ""
612 | }
613 | { "In {\em " booktitle * "\/}" * }
614 | if$
615 | }
616 | { "In " key * }
617 | if$
618 | }
619 | { "In " format.crossref.editor * }
620 | if$
621 | " \cite{" * crossref * "}" *
622 | }
623 |
624 | FUNCTION {article}
625 | { output.bibitem
626 | format.authors "author" output.check
627 | new.block
628 | format.title "title" output.check
629 | new.block
630 | crossref missing$
631 | { format.journal.vol.num.date output
632 | format.pages output
633 | }
634 | { format.article.crossref output.nonnull
635 | format.pp.pages output
636 | }
637 | if$
638 | new.block
639 | note output
640 | fin.entry
641 | }
642 |
643 | FUNCTION {book}
644 | { output.bibitem
645 | author empty$
646 | { format.editors "author and editor" output.check }
647 | { format.authors output.nonnull
648 | crossref missing$
649 | { "author and editor" editor either.or.check }
650 | 'skip$
651 | if$
652 | }
653 | if$
654 | new.block
655 | format.btitle "title" output.check
656 | format.edition output
657 | crossref missing$
658 | { format.bvolume output
659 | new.block
660 | format.number.series output
661 | new.sentence
662 | publisher "publisher" output.check
663 | address output
664 | }
665 | { new.block
666 | format.book.crossref output.nonnull
667 | }
668 | if$
669 | format.date "year" output.check
670 | new.block
671 | note output
672 | fin.entry
673 | }
674 |
675 | FUNCTION {booklet}
676 | { output.bibitem
677 | format.authors output
678 | new.block
679 | format.title "title" output.check
680 | howpublished address new.block.checkb
681 | howpublished output
682 | address output
683 | format.date output
684 | new.block
685 | note output
686 | fin.entry
687 | }
688 |
689 | FUNCTION {inbook}
690 | { output.bibitem
691 | author empty$
692 | { format.editors "author and editor" output.check }
693 | { format.authors output.nonnull
694 | crossref missing$
695 | { "author and editor" editor either.or.check }
696 | 'skip$
697 | if$
698 | }
699 | if$
700 | new.block
701 | format.btitle "title" output.check
702 | format.edition output
703 | crossref missing$
704 | { format.bvolume output
705 | new.block
706 | format.number.series output
707 | new.sentence
708 | publisher "publisher" output.check
709 | address output
710 | }
711 | { new.block
712 | format.book.crossref output.nonnull
713 | }
714 | if$
715 | format.date "year" output.check
716 | format.chapter.pages "chapter and pages" output.check
717 | new.block
718 | note output
719 | fin.entry
720 | }
721 |
722 | FUNCTION {incollection}
723 | { output.bibitem
724 | format.authors "author" output.check
725 | new.block
726 | format.title "title" output.check
727 | new.block
728 | crossref missing$
729 | { format.in.ed.booktitle "booktitle" output.check
730 | format.edition output
731 | format.bvolume output
732 | format.number.series output
733 | new.sentence
734 | publisher "publisher" output.check
735 | address output
736 | format.date "year" output.check
737 | }
738 | { format.incoll.inproc.crossref output.nonnull }
739 | if$
740 | format.chapter.pages output
741 | new.block
742 | note output
743 | fin.entry
744 | }
745 |
746 | FUNCTION {inproceedings}
747 | { output.bibitem
748 | format.authors "author" output.check
749 | new.block
750 | format.title "title" output.check
751 | new.block
752 | crossref missing$
753 | { format.in.proc.date "booktitle" output.check
754 | format.ineditors output
755 | format.bvolume output
756 | format.number.series output
757 | organization output
758 | publisher output
759 | }
760 | { format.incoll.inproc.crossref output.nonnull }
761 | if$
762 | format.pp.pages output
763 | new.block
764 | note output
765 | fin.entry
766 | }
767 |
768 | FUNCTION {conference} { inproceedings }
769 |
770 | FUNCTION {manual}
771 | { output.bibitem
772 | author empty$
773 | { organization scapify output }
774 | { format.authors output.nonnull }
775 | if$
776 | new.block
777 | format.btitle "title" output.check
778 | format.edition output
779 | author empty$
780 | { address new.block.checka }
781 | { organization address new.block.checkb
782 | organization output
783 | }
784 | if$
785 | address output
786 | format.date output
787 | new.block
788 | note output
789 | fin.entry
790 | }
791 |
792 | FUNCTION {mastersthesis}
793 | { output.bibitem
794 | format.authors "author" output.check
795 | new.block
796 | format.title "title" output.check
797 | new.block
798 | "Master's thesis" format.thesis.type output.nonnull
799 | school "school" output.check
800 | address output
801 | format.date "year" output.check
802 | new.block
803 | note output
804 | fin.entry
805 | }
806 |
807 | FUNCTION {misc}
808 | { output.bibitem
809 | format.authors output
810 | title howpublished new.block.checkb
811 | format.title output
812 | howpublished new.block.checka
813 | howpublished output
814 | format.date output
815 | new.block
816 | note output
817 | fin.entry
818 | empty.misc.check
819 | }
820 |
821 | FUNCTION {phdthesis}
822 | { output.bibitem
823 | format.authors "author" output.check
824 | new.block
825 | format.btitle "title" output.check
826 | new.block
827 | "PhD thesis" format.thesis.type output.nonnull
828 | school "school" output.check
829 | address output
830 | format.date "year" output.check
831 | new.block
832 | note output
833 | fin.entry
834 | }
835 |
836 | FUNCTION {proceedings}
837 | { output.bibitem
838 | editor empty$
839 | { organization scapify output }
840 | { format.editors output.nonnull }
841 | if$
842 | new.block
843 | title format.proc.date "title" output.check
844 | format.bvolume output
845 | format.number.series output
846 | editor empty$
847 | 'skip$
848 | { organization output }
849 | if$
850 | publisher output
851 | new.block
852 | note output
853 | fin.entry
854 | }
855 |
856 | FUNCTION {techreport}
857 | { output.bibitem
858 | format.authors "author" output.check
859 | new.block
860 | format.title "title" output.check
861 | new.block
862 | format.tr.number output.nonnull
863 | institution "institution" output.check
864 | address output
865 | format.date "year" output.check
866 | new.block
867 | note output
868 | fin.entry
869 | }
870 |
871 | FUNCTION {unpublished}
872 | { output.bibitem
873 | format.authors "author" output.check
874 | new.block
875 | format.title "title" output.check
876 | new.block
877 | note "note" output.check
878 | format.date output
879 | fin.entry
880 | }
881 |
882 | FUNCTION {default.type} { misc }
883 |
884 | MACRO {jan} {"Jan."}
885 |
886 | MACRO {feb} {"Feb."}
887 |
888 | MACRO {mar} {"Mar."}
889 |
890 | MACRO {apr} {"Apr."}
891 |
892 | MACRO {may} {"May"}
893 |
894 | MACRO {jun} {"June"}
895 |
896 | MACRO {jul} {"July"}
897 |
898 | MACRO {aug} {"Aug."}
899 |
900 | MACRO {sep} {"Sept."}
901 |
902 | MACRO {oct} {"Oct."}
903 |
904 | MACRO {nov} {"Nov."}
905 |
906 | MACRO {dec} {"Dec."}
907 |
908 | MACRO {acmcs} {"ACM Comput. Surv."}
909 |
910 | MACRO {acta} {"Acta Inf."}
911 |
912 | MACRO {cacm} {"Commun. ACM"}
913 |
914 | MACRO {ibmjrd} {"IBM J. Res. Dev."}
915 |
916 | MACRO {ibmsj} {"IBM Syst.~J."}
917 |
918 | MACRO {ieeese} {"IEEE Trans. Softw. Eng."}
919 |
920 | MACRO {ieeetc} {"IEEE Trans. Comput."}
921 |
922 | MACRO {ieeetcad}
923 | {"IEEE Trans. Comput.-Aided Design Integrated Circuits"}
924 |
925 | MACRO {ipl} {"Inf. Process. Lett."}
926 |
927 | MACRO {jacm} {"J.~ACM"}
928 |
929 | MACRO {jcss} {"J.~Comput. Syst. Sci."}
930 |
931 | MACRO {scp} {"Sci. Comput. Programming"}
932 |
933 | MACRO {sicomp} {"SIAM J. Comput."}
934 |
935 | MACRO {tocs} {"ACM Trans. Comput. Syst."}
936 |
937 | MACRO {tods} {"ACM Trans. Database Syst."}
938 |
939 | MACRO {tog} {"ACM Trans. Gr."}
940 |
941 | MACRO {toms} {"ACM Trans. Math. Softw."}
942 |
943 | MACRO {toois} {"ACM Trans. Office Inf. Syst."}
944 |
945 | MACRO {toplas} {"ACM Trans. Program. Lang. Syst."}
946 |
947 | MACRO {tcs} {"Theoretical Comput. Sci."}
948 |
949 | READ
950 |
951 | FUNCTION {sortify}
952 | { purify$
953 | "l" change.case$
954 | }
955 |
956 | INTEGERS { len }
957 |
958 | FUNCTION {chop.word}
959 | { 's :=
960 | 'len :=
961 | s #1 len substring$ =
962 | { s len #1 + global.max$ substring$ }
963 | 's
964 | if$
965 | }
966 |
967 | FUNCTION {sort.format.names}
968 | { 's :=
969 | #1 'nameptr :=
970 | ""
971 | s num.names$ 'numnames :=
972 | numnames 'namesleft :=
973 | { namesleft #0 > }
974 | { nameptr #1 >
975 | { " " * }
976 | 'skip$
977 | if$
978 | s nameptr "{vv{ } }{ll{ }}{ f{ }}{ jj{ }}" format.name$ 't :=
979 | nameptr numnames = t "others" = and
980 | { "et al" * }
981 | { t sortify * }
982 | if$
983 | nameptr #1 + 'nameptr :=
984 | namesleft #1 - 'namesleft :=
985 | }
986 | while$
987 | }
988 |
989 | FUNCTION {sort.format.title}
990 | { 't :=
991 | "A " #2
992 | "An " #3
993 | "The " #4 t chop.word
994 | chop.word
995 | chop.word
996 | sortify
997 | #1 global.max$ substring$
998 | }
999 |
1000 | FUNCTION {author.sort}
1001 | { author empty$
1002 | { key empty$
1003 | { "to sort, need author or key in " cite$ * warning$
1004 | ""
1005 | }
1006 | { key sortify }
1007 | if$
1008 | }
1009 | { author sort.format.names }
1010 | if$
1011 | }
1012 |
1013 | FUNCTION {author.editor.sort}
1014 | { author empty$
1015 | { editor empty$
1016 | { key empty$
1017 | { "to sort, need author, editor, or key in " cite$ * warning$
1018 | ""
1019 | }
1020 | { key sortify }
1021 | if$
1022 | }
1023 | { editor sort.format.names }
1024 | if$
1025 | }
1026 | { author sort.format.names }
1027 | if$
1028 | }
1029 |
1030 | FUNCTION {author.organization.sort}
1031 | { author empty$
1032 | { organization empty$
1033 | { key empty$
1034 | { "to sort, need author, organization, or key in " cite$ * warning$
1035 | ""
1036 | }
1037 | { key sortify }
1038 | if$
1039 | }
1040 | { "The " #4 organization chop.word sortify }
1041 | if$
1042 | }
1043 | { author sort.format.names }
1044 | if$
1045 | }
1046 |
1047 | FUNCTION {editor.organization.sort}
1048 | { editor empty$
1049 | { organization empty$
1050 | { key empty$
1051 | { "to sort, need editor, organization, or key in " cite$ * warning$
1052 | ""
1053 | }
1054 | { key sortify }
1055 | if$
1056 | }
1057 | { "The " #4 organization chop.word sortify }
1058 | if$
1059 | }
1060 | { editor sort.format.names }
1061 | if$
1062 | }
1063 |
1064 | FUNCTION {presort}
1065 | { type$ "book" =
1066 | type$ "inbook" =
1067 | or
1068 | 'author.editor.sort
1069 | { type$ "proceedings" =
1070 | 'editor.organization.sort
1071 | { type$ "manual" =
1072 | 'author.organization.sort
1073 | 'author.sort
1074 | if$
1075 | }
1076 | if$
1077 | }
1078 | if$
1079 | " "
1080 | *
1081 | year field.or.null sortify
1082 | *
1083 | " "
1084 | *
1085 | title field.or.null
1086 | sort.format.title
1087 | *
1088 | #1 entry.max$ substring$
1089 | 'sort.key$ :=
1090 | }
1091 |
1092 | ITERATE {presort}
1093 |
1094 | SORT
1095 |
1096 | STRINGS { longest.label }
1097 |
1098 | INTEGERS { number.label longest.label.width }
1099 |
1100 | FUNCTION {initialize.longest.label}
1101 | { "" 'longest.label :=
1102 | #1 'number.label :=
1103 | #0 'longest.label.width :=
1104 | }
1105 |
1106 | FUNCTION {longest.label.pass}
1107 | { number.label int.to.str$ 'label :=
1108 | number.label #1 + 'number.label :=
1109 | label width$ longest.label.width >
1110 | { label 'longest.label :=
1111 | label width$ 'longest.label.width :=
1112 | }
1113 | 'skip$
1114 | if$
1115 | }
1116 |
1117 | EXECUTE {initialize.longest.label}
1118 |
1119 | ITERATE {longest.label.pass}
1120 |
1121 | FUNCTION {begin.bib}
1122 | { preamble$ empty$
1123 | 'skip$
1124 | { preamble$ write$ newline$ }
1125 | if$
1126 | "\begin{thebibliography}{" longest.label * "}" * write$ newline$
1127 | }
1128 |
1129 | EXECUTE {begin.bib}
1130 |
1131 | EXECUTE {init.state.consts}
1132 |
1133 | ITERATE {call.type$}
1134 |
1135 | FUNCTION {end.bib}
1136 | { newline$
1137 | "\end{thebibliography}" write$ newline$
1138 | }
1139 |
1140 | EXECUTE {end.bib}
1141 |
--------------------------------------------------------------------------------
/figures/universal-sequence.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------