/
versions.html
219 lines (176 loc) · 6.11 KB
/
versions.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Readme</title>
<link href="./elib1.css" rel="stylesheet">
<script src="../../include/jquery-1.3.2.min.js" type="text/javascript"></script>
</head>
<body><chap>
<h1 class="title">Versions</h1>
<p>Suppose we have several versions of the <i>same</i> module (for
example the <c>lists</c> module) throughout the lifetime of Erlang
the lists module has been changed many times - suppoe it was
important to know <i>exactyl which version of lists we mean</i> when
talking about the lists module?</p>
<h1>Problems with names</h1>
<dl>
<dt>The Name collision problem</dt>
<dd>
<p>How can we make sure that moudle names don't collide? In
Erlang module names must be unique. Ho can two independentally
developed program guyarantee that the modukles names they use
don't collide?</p>
</dd>
<dt>The Authentication Problem</dt>
<dd>
<p>How can we be sure that <c>bing.erl</c> was written by
<c>Alice</c>?. We trust the code written by Alice, how can we
be sure that nobody else has tampered with <c>bing.erl</c>?</p>
</dd>
<dt>
The Testing Problem
</dt>
<dd>
<p>On some date we tested some partticular collection of modules
and something went wrong. We want to report a bug. How can we
make sure that we can precisely identifcy exactly whhich modue
were used so that the bug can be reproduced?</p>
</dd>
</dl>
<h1>Module Version and Authentication Tagging</h1>
<p>We propose some new annotations what can be used to precisely identify
a moduke and its prove authorship of the module.</p>
<p>We'll start with an example. Alice starts by writing the module <c>foo</c>
Her first version of the module looks like this:</p>
<pre>
-module(foo).
-export([a/1]).
%% Version$author:Alice$
%% Version$end$
a(X) ->
Y = lists:reverse(X),
foo:baz(Y).
</pre>
<p>Alice tests her program and wishes to publish the program. She
gives the shell command <c>publish</c>. This modifies foo.erl as
follows:</p>
<pre>
-module(foo).
-export([a/1]).
%% Version$author:Alice$
%% Do not edit the Version Block By Hand
-version(lists,"a23545f1acd365231626217365bcad2").
-version(foo, "a23545f1acd365231626217365bcad2").
-version(foo, "623547254726547254725472574527").
-author(foo,alice,"1625371537136512436143654").
%% Version$end$
a(X) ->
Y = lists:reverse(X),
foo:baz(Y).
</pre>
<p>
The annotatiion <c>version(Mod, C)</c> means that <i>The module</i>
<c>M</c> <i>that Alice has tested foo has MD5 checksum</i> <c>C</c>.
<c>-author(foo,alice,S)</c> provides a proof that Alice has written
foo. <c>S</c> is the checksum of <c>foo</c> signed with Alices
public key.
</p>
<p>When this module is now compiled the compiler will compile the
code as if Aliuce had written:</p>
<pre>
-module(foo).
-export([a/1]).
a(X) ->
Y = 'a23545f1acd365231626217365bcad2':reverse(X),
'623547254726547254725472574527':baz(Y).
</pre>
<p>And instead of producing <c>foo.beam</c> the compler will prodiuce
a file called:<c>XXX.beam</c></p>
<h1>The name transformation</h1>
<h2>Step 1 - creating a name map</h2>
<p>The first stup is to create a “name map” of all the files in the
current directory:</p>
<pre>
> elib1_publish:publish().
[elib1_lin,elib1_rsa,io_lib_pretty,filelib]
</pre>
<p>This lists the files which have been added to the name map. The
name map is stored in a file called <c>nmape.erl</c>. The first few lines of this
file look like this:</p>
<pre>
-module(nmap).
%% autogenerated do not edit by hand.
-export([map/0]).
map()->
[{elib1_lin,"elib1_lin.erl","joe",
mBA4EEB84C7300F1E41DBA739A5B6B5CD,
5006509289449511917694936...},
{elib1_publish,"elib1_publish.erl","joe",
m82025D6B593F591DCA2C22A7B43DB6EC,
63646454995546639274897433290083170...},
...
].
</pre>
<p>the name mape is a list of <c>{Mod, File, Who, Md5, Certificate}</c>
tuples, where:</p>
<dl>
<dt>Mod</dt>
<dd><p>Is a module name</p></dd>
<dt>File</dt>
<dd><p>Is the file name of the file containing the module</p></dd>
<dt>Who</dt>
<dd><p>Is the name of the person signig the module</p></dd>
<dt>Md5</dt>
<dd><p>Is an atom containing an imbedded MD5 checkum of the
contents of <c>File</c></p></dd>
<dt>Certificate</dt>
<dd><p>Is the RSA digital signature of
the Md5 checksum signed with <c>Who</c>'s private key.</p></dd>
</dl>
<h2>Step two - compileing with the name map</h2>
<pre>
> elib1_publish:compile().
creating:"mBA4EEB84C7300F1E41DBA739A5B6B5CD.beam"
creating:"m82025D6B593F591DCA2C22A7B43DB6EC.beam"
creating:"m79D5C6A6F882B11991744F7B2606CA64.beam"
creating:"m446C085CB7758C195CF3CF95B16C9DB0.beam"
creating:"m07A010C6CA0E9A4140EBA235E724F77A.beam"
</pre>
<p>Once we have a name map we can transform all the erlang in the
current directory into an equivalent set of modules <i>where all the
module names have bee replaced by the MD5 sums of the content of the
original source code files containing the modules.</i></p>
<p>Everythjing remains consistent, providing we can call
</p>
<p>This means that the md5 checksum of x1.erl is m273 .... and 2135... is
the MD5 sum signed
with joe's public key</p>
<p>transform all code in x1.erl x2.erl replacing the module names x1,
x2 ... etc.
with the MD5 sums so x1:abc(...) becomes m273...:abc( ...)
</p>
<p>replace apply(M,F,A) with newapply(map(),M, F, A)</p>
<pre>
result - a) no name space collisions
b) exact version control
c) safety (if you can't guess the MD5 sum :-)
</pre>
<p>It's kind of like adding a big "where" clause round a module</p>
<pre>
-module(foo).
a() -> lists:reverse(...)
WHERE
foo = m1283abcd ...
lists = m34aefg ...
</pre>
<p>ie all modules names are converted to the MD5 sums of the original sources.
</p>
<p>This is used to solve a lot of problems with safety, versioning,
testing, namespaces etc.</p>
<p>
(safe erlang can be made by replacing calls to dangerous mods like file etc.
with safe_file ... etc.)
</p>
</chap></body>
</html>