-
Notifications
You must be signed in to change notification settings - Fork 26
/
Broadcast.daml
153 lines (130 loc) · 4.3 KB
/
Broadcast.daml
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
-- Copyright (c) 2019 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
-- SPDX-License-Identifier: Apache-2.0
daml 1.2
module Broadcast where
import DA.Action
data Something = Something with
deriving (Eq, Show)
data BroadcastKey = BroadcastKey with
broadcaster : Party
id : Text
deriving (Eq, Show)
data SubscriptionKey = SubscriptionKey with
broadcast : BroadcastKey
subscriber : Party
deriving (Eq, Show)
template BroadcastData
with
broadcast : BroadcastKey
payload : Something
where
signatory broadcast.broadcaster
key broadcast : BroadcastKey
maintainer key.broadcaster
template BroadcastSubscription
with
subscription : SubscriptionKey
currentDataCid : ContractId BroadcastData
currentData : BroadcastData
where
signatory subscription.broadcast.broadcaster, subscription.subscriber
key subscription : SubscriptionKey
maintainer key.broadcast.broadcaster
controller subscription.broadcast.broadcaster can
UpdateData : ContractId BroadcastSubscription
with
newDataCid : ContractId BroadcastData
do
-- This `fetch` ensures the new data lands in the subscriber's PCS
newData <- fetch newDataCid
create this with
currentDataCid = newDataCid
currentData = newData
template SubscriptionRequest
with
broadcast : BroadcastKey
subscriber : Party
where
signatory subscriber
controller broadcast.broadcaster can
AcceptSubscription : ContractId BroadcastSubscription
with
currentDataCid : ContractId BroadcastData
do
-- This `fetch` ensures the current data lands in the subscriber's PCS
currentData <- fetch currentDataCid
create BroadcastSubscription with
subscription = SubscriptionKey with
broadcast
subscriber
currentDataCid
currentData
template Broadcast
with
broadcast : BroadcastKey
subscribers : [Party]
where
signatory broadcast.broadcaster
key broadcast : BroadcastKey
maintainer key.broadcaster
controller broadcast.broadcaster can
nonconsuming BroadcastUpdate : [ContractId BroadcastSubscription]
with
newPayload : Something
do
(oldDataCid, oldData) <- fetchByKey @BroadcastData (key this)
archive oldDataCid
let newData = oldData with payload = newPayload
newDataCid <- create newData
forA subscribers
(\subscriber -> do
(subCid, _) <- fetchByKey @BroadcastSubscription
SubscriptionKey with
broadcast = key this
subscriber
exercise subCid UpdateData with
newDataCid
)
AddSubscriber : (ContractId Broadcast, ContractId BroadcastSubscription)
with
reqCid : ContractId SubscriptionRequest
do
(currentDataCid, currentData) <- fetchByKey @BroadcastData (key this)
req <- fetch reqCid
bc <- create this with
subscribers = req.subscriber :: subscribers
bs <- exercise reqCid AcceptSubscription with currentDataCid
return (bc, bs)
test_broadcast = scenario do
broadcaster <- getParty "Alice"
subscribers <- mapA getParty $ map (\i -> "Subscriber" <> show i) [1..5]
let
broadcast = BroadcastKey with
broadcaster
id = "Broadcast"
dataCid <- submit broadcaster do
create BroadcastData with
broadcast
payload = Something with
bcCid <- submit broadcaster do
create Broadcast with
broadcast
subscribers = []
let
addSubscriber subscriber (bcCid : ContractId Broadcast) = do
reqCid <- submit subscriber do
create SubscriptionRequest with
broadcast
subscriber
(newBcCid, _) <- submit broadcaster do
exercise bcCid AddSubscriber with reqCid
return newBcCid
updateData (bcCid : ContractId Broadcast) = do
submit broadcaster do
exercise bcCid BroadcastUpdate with
newPayload = Something with
addAndUpdate (bcCid : ContractId Broadcast) subscriber = do
newBcCid <- addSubscriber subscriber bcCid
updateData newBcCid
return newBcCid
foldlA addAndUpdate bcCid subscribers