-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathtestchainmailmain.js
151 lines (119 loc) · 4.16 KB
/
testchainmailmain.js
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
// Options: --free-variable-checker --require --validate
/*global module require*/
module.exports = (function(){
"use strict";
const {def} = require('./src/sesshim.js');
const {chainmail} = require('./test/jessie/quasi-chainmail.js');
console.log('----------');
// From https://www.doc.ic.ac.uk/~scd/Holistic_Specs.WG2.3.pdf
const mintMakerSpec = chainmail`
# An Assay is pass-by-copy data that, interpreted in the context of a
# given Issuer, represents some set of erights as issued by that
# Issuer. This is referred to as an "amount", though it is not
# necessarily a number or quantity. Every Assay type must be able to
# represent the empty set of erights.
specification Issuer[Assay] {
specification Mint {
method getIssuer() :Issuer;
# Where new units come from
method mint(amount ?Assay) :Purse;
field currency:Nat;
field internal:Set;
policy internal_mba_1
forall (b:Mint, x) {
(x in b::internal) iff {
(x === b) or ((x isa Purse) and (x::mint === b));
};
}
# I don't understand mba_2
}
specification Purse {
method getIssuer() :Issuer;
# The set of erights currently in the purse.
method getBalance() :Assay;
# Move 'amount' erights from 'src' into this purse.
method deposit(amount ?Assay, src ?Purse);
field mint obeys Mint;
field balance:Nat;
policy transfer_1
# With two purses of same mint one can transfer money between them.
forall (a1:Purse, a2:Purse, b1:Nat, b2:Nat, amt:Nat) {
a1 !== a2;
a1::mint === a2::mint;
a1::balance === b1 and b1 > amt;
a2::balance === b2;
calls a2.deposit(amt, a1);
} implies will {
a1::balance === b1 - amt;
a2::balance === b2 + amt;
}
policy violate_conserve_2
# Only someone with the mint of a given currency can violate
# conservation of that currency.
# If some execution which starts now and which involves at most the
# objects from S modifies b::currency at some future time, then at
# least one of the objects in S can access b directly now, and this
# object is not internal to b.
forall (b:Mint) {
will ((changes b::currency) @ S);
} implies exists (o in S) {
o in S;
o canAccess b;
not (o in b::internal);
}
policy violate_conserve_2_equiv
forall (b:Mint) {
forall (o in S) {
(not (o canAccess b) or (o in b::internal)) implies
not ((will (changes b::currency)) @ S);
};
}
policy violate_conserve_2_reformulate
# A set S whose elements have direct access to b only if they are
# internal to b is insufficient to modify b.currency.
forall (b:Mint) {
forall (o in S) {
((o canAccess b) only if (o in b::internal)) implies
not ((will (changes b::currency)) @ S);
};
}
policy inflate_3
# The bank can only inflate its own currency
{ # TODO
}
policy must_have_4
# No one can affect the balance of a purse they do not have.
forall (a:Purse) {
will ((changes a::balance) @ S) only if exists (o in S) {
o canAccess a;
not (o in a::internal);
};
}
policy non_neg_5
# Balances are always non-negative.
{ # TODO
}
policy trust_6
# A reported successful deposit can be trusted as much as one trusts
# the purse one is depositing to.
{ # TODO
}
}
# Make a fresh purse initially holding no erights (the empty set of
# erights), but able to hold the kinds of erights managed by this
# issuer.
method makeEmptyPurse() :Purse;
# Convenience for making a fresh empty purse, transfering 'amount'
# into it from this one, and returning it.
method getExclusive(amount ?Assay, src ?Purse) :Purse;
# 'includes' asks whether 'providedAmount' describes a set of erights
# that includes all erights in the set described by 'neededAmount'.
#
# The parameter names suggest only one of two major use
# cases. The other is 'includes(offeredAmount, takenAmount)'
method includes(providedAmount ?Assay, neededAmount ?Assay);
}
`;
console.log(JSON.stringify(mintMakerSpec, undefined, ' '));
return def({mintMakerSpec});
}());