-
Notifications
You must be signed in to change notification settings - Fork 3
/
locker.rho
88 lines (84 loc) · 2.65 KB
/
locker.rho
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
new Locker,
trace(`rho:io:stderr`),
stdout(`rho:io:stdout`),
insertArbitrary(`rho:registry:insertArbitrary`),
lookup(`rho:registry:lookup`)
in {
// Test / demo
new lockerCh, ackCh, rx in {
Locker!("deadbeef".hexToBytes(), *lockerCh) | for (locker <- lockerCh) {
// trace!({"locker": *locker}) |
new trinket, updateCh in {
trace!({"trinket": *trinket}) |
locker!("update", "beef".hexToBytes(), 0, {"trinket": *trinket}, *trace, *ackCh)
} |
// trinket has gone out of scope but
// we can get it back if we have the locker combo.
for(_ <- ackCh) {
locker!("get", "beef".hexToBytes(), 1, *trace, *rx) |
for(@{"trinket": trinket} <- rx) {
trace!({"win! got trinket": trinket})
}
}
}
}
|
new uriCh in {
insertArbitrary!(*Locker, *uriCh) | for(@uri <- uriCh) {
stdout!(["#define $Locker",uri])
}
}
|
contract Locker(@{pubKey /\ ByteArray}, return) = {
new self, itemsCh, nonceCh in {
trace!("making locker") |
return!(bundle+{*self}) |
itemsCh!({}) |
nonceCh!(-1) |
contract self(@"getNonce", return) = { for(@nonce <- nonceCh) { return!(nonce) | nonceCh!(nonce) } } |
contract self(@"update", @{sig /\ ByteArray}, @{nextNonce /\ Int}, @{more /\ {..._}}, fail, ack) = {
trace!({"locker.update": more}) |
for(@nonce <- nonceCh) {
if (nonce + 1 != nextNonce) {
fail!({"expected nonce": nonce + 1}) |
nonceCh!(nonce)
} else {
nonceCh!(nextNonce) |
// TODO: real sig checking over nonce, more.keys()
if ("dead".hexToBytes() ++ sig != pubKey) {
fail!("bad signature")
} else {
for (@items <- itemsCh) {
// trace!({"items": items, "more": more}) |
itemsCh!(items.union(more)) |
ack!(Nil)
}
}
}
}
}
|
contract self(@"get", @{sig /\ ByteArray}, @nextNonce, fail, return) = {
trace!("locker.get(...)") |
for(@nonce <- nonceCh) {
if (nonce + 1 != nextNonce) {
fail!({"expected nonce": nonce + 1}) |
nonceCh!(nonce)
} else {
nonceCh!(nextNonce) |
// TODO: real sig checking over nonce
if ("dead".hexToBytes() ++ sig != pubKey) {
fail!("bad signature")
} else {
for (@items <- itemsCh) {
// trace!({"get items": items}) |
itemsCh!(items) |
return!(items)
}
}
}
}
}
}
}
}