-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.rsh
More file actions
113 lines (96 loc) · 3 KB
/
index.rsh
File metadata and controls
113 lines (96 loc) · 3 KB
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
'reach 0.1';
const [isCount, ZERO, ONE, TWO, THREE, FOUR, FIVE] = makeEnum(6);
const [isGuess, GZERO, GONE, GTWO, GTHREE, GFOUR, GFIVE, GSIX, GSEVEN, GEIGHT, GNINE, GTEN] = makeEnum(11);
const [isOutcome, A_WINS, DRAW, B_WINS] = makeEnum(3);
const winner = (aCount, aGuess, bCount, bGuess) => {
const total = aCount + bCount
if (aGuess == bGuess) {
return DRAW
} else if (total == aGuess) {
return A_WINS
} else if (total == bGuess) {
return B_WINS
} else {
return DRAW
}
}
forall(UInt, aCount =>
forall(UInt, aGuess =>
forall(UInt, bCount =>
forall(UInt, bGuess =>
assert(isOutcome(winner(aCount, aGuess, bCount, bGuess)))))));
const commonInteract = {
...hasRandom,
getCount: Fun([], UInt),
getGuess: Fun([], UInt),
seeOutcome: Fun([UInt], Null),
informTimeout: Fun([], Null)
}
export const main = Reach.App(() => {
const A = Participant('Alice', {
...commonInteract,
wager: UInt,
deadline: UInt,
});
const B = Participant('Bob', {
...commonInteract,
acceptWager: Fun([UInt], Null)
});
init();
const informTimeout = () => {
each([A, B], () => {
interact.informTimeout();
});
};
A.only(() => {
const wager = declassify(interact.wager);
const deadline = declassify(interact.deadline);
})
A.publish(wager, deadline).pay(wager);
commit();
B.only(() => {
interact.acceptWager(wager)
})
B.publish().pay(wager).timeout(relativeTime(deadline), () => closeTo(A, informTimeout));
var outcome = DRAW;
invariant(balance() == 2 * wager && isOutcome(outcome));
while (outcome == DRAW) {
commit();
A.only(() => {
const _aCount = interact.getCount();
const [_aCountCommit, _aCountSalt] = makeCommitment(interact, _aCount);
const aCountCommit = declassify(_aCountCommit);
const _aGuess = interact.getGuess();
const [_aGuessCommit, _aGuessSalt] = makeCommitment(interact, _aGuess);
const aGuessCommit = declassify(_aGuessCommit);
});
A.publish(aCountCommit, aGuessCommit)
.timeout(relativeTime(deadline), () => closeTo(B, informTimeout));
commit();
unknowable(B, A(_aCount, _aCountSalt, _aGuess, _aGuessSalt));
B.only(() => {
const bCount = declassify(interact.getCount());
const bGuess = declassify(interact.getGuess());
})
B.publish(bCount, bGuess)
.timeout(relativeTime(deadline), () => closeTo(A, informTimeout));
commit();
A.only(() => {
const aCount = declassify(_aCount);
const aCountSalt = declassify(_aCountSalt);
const aGuess = declassify(_aGuess);
const aGuessSalt = declassify(_aGuessSalt);
});
A.publish(aCount, aCountSalt, aGuess, aGuessSalt)
.timeout(relativeTime(deadline), () => closeTo(B, informTimeout));
outcome = winner(aCount, aGuess, bCount, bGuess);
continue;
}
assert(outcome == A_WINS || outcome == B_WINS);
transfer(wager * 2).to(outcome == A_WINS ? A : B)
commit();
each([A, B], () => {
interact.seeOutcome(outcome)
})
exit();
});