blueprint.gno
6.78 Kb · 248 lines
1package blueprint
2
3import (
4 "chain"
5 "chain/banker"
6 "chain/runtime"
7 "chain/runtime/unsafe"
8 "strconv"
9
10 "gno.land/p/g1nqnrt3aldzhu6zzeg75yw97wvavqy7wr77g56q/deploy-test/v2/accesscontrol"
11 "gno.land/p/g1nqnrt3aldzhu6zzeg75yw97wvavqy7wr77g56q/deploy-test/v2/validate"
12 "gno.land/r/g1nqnrt3aldzhu6zzeg75yw97wvavqy7wr77g56q/deploy-test/v2/admin"
13 personal_world "gno.land/r/g1nqnrt3aldzhu6zzeg75yw97wvavqy7wr77g56q/deploy-test/v2/personal_world"
14)
15
16const (
17 CreateBlueprintEvent = "CreateBlueprint"
18 UpdateBlueprintEvent = "UpdateBlueprint"
19 DeleteBlueprintEvent = "DeleteBlueprint"
20 SetBlueprintMetadataEvent = "SetBlueprintMetadata"
21)
22
23func CreateBlueprint(cur realm, propKeys string, propValues string) uint32 {
24 assertNotFrozen()
25 caller := accesscontrol.MustGetUserCaller(0, cur)
26
27 props := parsePropsCSV(propKeys, propValues)
28 blueprintCreateValidator.MustValidate(props)
29
30 biomeName := props["biome"]
31 name := props["name"]
32 size := props["size"]
33
34 assertBiomeName(biomeName)
35 assertBiomeExists(biomeName)
36 assertBlueprintName(name)
37 assertBlueprintSize(size)
38
39 if !blueprintStore.IsNameAvailable(name) {
40 panic("name already exists")
41 }
42
43 cost := creationCost
44 if cost > 0 {
45 // MustGetUserCaller guarantees a direct user call before reading OriginSend.
46 payment := unsafe.OriginSend().AmountOf("ugnot")
47 assertExactPayment(cost, payment)
48 }
49
50 heightStr := strconv.FormatInt(runtime.ChainHeight(), 10)
51 props["owner"] = caller.String()
52 props["createdAt"] = heightStr
53 props["updatedAt"] = heightStr
54
55 id := blueprintStore.Create(props)
56 idStr := formatBlueprintID(id)
57 if cost > 0 {
58 send(cur, admin.GetFeeCollector(), cost)
59 }
60
61 chain.Emit(
62 CreateBlueprintEvent,
63 "id", idStr,
64 "owner", props["owner"],
65 "name", props["name"],
66 "biome", props["biome"],
67 "cost", strconv.FormatInt(cost, 10),
68 )
69
70 return id
71}
72
73func UpdateBlueprint(cur realm, blueprintID uint32, propKeys string, propValues string) {
74 assertNotFrozen()
75 caller := accesscontrol.MustGetUserCaller(0, cur)
76 assertAdminOrBlueprintOwner(blueprintID, caller)
77
78 props := parsePropsCSV(propKeys, propValues)
79 blueprintUpdateValidator.MustValidate(props)
80 blueprintStore.AssertBlueprintExists(blueprintID)
81
82 if name, found := props["name"]; found {
83 assertBlueprintName(name)
84 }
85
86 props["updatedAt"] = strconv.FormatInt(runtime.ChainHeight(), 10)
87
88 updated := blueprintStore.Update(blueprintID, props)
89
90 chain.Emit(
91 UpdateBlueprintEvent,
92 "id", updated["id"],
93 "owner", updated["owner"],
94 "name", updated["name"],
95 )
96}
97
98func DeleteBlueprint(cur realm, blueprintID uint32) {
99 assertNotFrozen()
100 accesscontrol.AssertIsAdminOrOperator(0, cur, admin.IsAdmin, admin.IsOperator)
101
102 blueprintStore.Delete(blueprintID)
103 verifierStore.Delete(blueprintID)
104
105 chain.Emit(
106 DeleteBlueprintEvent,
107 "id", formatBlueprintID(blueprintID),
108 )
109}
110
111func SetBlueprintMetadata(cur realm, blueprintID uint32, metadata string) {
112 assertNotFrozen()
113 accesscontrol.AssertIsAdmin(0, cur, admin.IsAdmin)
114 blueprintStore.AssertBlueprintExists(blueprintID)
115 validate.AssertStringTextLen(metadata, true, "blueprint metadata")
116 blueprintStore.SetMetadata(blueprintID, metadata)
117
118 chain.Emit(
119 SetBlueprintMetadataEvent,
120 "id", formatBlueprintID(blueprintID),
121 )
122}
123
124func GetBlueprint(blueprintID uint32) map[string]string {
125 assertMigrationStateAvailable()
126 return blueprintStore.MustGet(blueprintID)
127}
128
129func GetBlueprintMetadata(blueprintID uint32) string {
130 assertMigrationStateAvailable()
131 return blueprintStore.GetMetadata(blueprintID)
132}
133
134func ListBlueprintMetadataByIDs(blueprintIDs ...uint32) []string {
135 assertMigrationStateAvailable()
136 assertListLimit("blueprintIDs", len(blueprintIDs))
137 return blueprintStore.ListMetadataByIDs(blueprintIDs...)
138}
139
140func GetBlueprintIDByName(name string) uint32 {
141 assertMigrationStateAvailable()
142 return blueprintStore.MustGetIDByName(name)
143}
144
145func GetTotalBlueprintSize() int {
146 assertMigrationStateAvailable()
147 return blueprintStore.Total()
148}
149
150func IsNameAvailable(name string) bool {
151 assertMigrationStateAvailable()
152 return blueprintStore.IsNameAvailable(name)
153}
154
155func ListBlueprintIDs(page int, count int) []uint32 {
156 assertMigrationStateAvailable()
157 assertListPageCount(page, count)
158 return blueprintStore.ListIDs(page, count)
159}
160
161func ListBlueprintsByIDs(blueprintIDs ...uint32) []map[string]string {
162 assertMigrationStateAvailable()
163 assertListLimit("blueprintIDs", len(blueprintIDs))
164
165 if len(blueprintIDs) == 0 {
166 return []map[string]string{}
167 }
168 return blueprintStore.ListByIDs(blueprintIDs...)
169}
170
171func GetBlueprintSizeByOwner(owner address) int {
172 assertMigrationStateAvailable()
173 return blueprintStore.OwnerCount(owner)
174}
175
176func ListBlueprintIDsByOwner(owner address, page int, count int) []uint32 {
177 assertMigrationStateAvailable()
178 assertListPageCount(page, count)
179 return blueprintStore.ListIDsByOwner(owner, page, count)
180}
181
182func GetBlueprintSizeByBiome(biomeName string) int {
183 assertMigrationStateAvailable()
184 assertBiomeName(biomeName)
185 assertBiomeExists(biomeName)
186 return blueprintStore.BiomeCount(biomeName)
187}
188
189func ListBlueprintIDsByBiome(biomeName string, page int, count int) []uint32 {
190 assertMigrationStateAvailable()
191 assertBiomeName(biomeName)
192 assertBiomeExists(biomeName)
193 assertListPageCount(page, count)
194 return blueprintStore.ListIDsByBiome(biomeName, page, count)
195}
196
197func GetBlueprintSizeByState(state string) int {
198 assertMigrationStateAvailable()
199 return blueprintStore.StateCount(state)
200}
201
202func ListBlueprintIDsByState(state string, page int, count int) []uint32 {
203 assertMigrationStateAvailable()
204 assertListPageCount(page, count)
205 return blueprintStore.ListIDsByState(state, page, count)
206}
207
208func GetBlueprintSizeByBiomeState(biomeName string, state string) int {
209 assertMigrationStateAvailable()
210 assertBiomeName(biomeName)
211 assertBiomeExists(biomeName)
212 return blueprintStore.BiomeStateCount(biomeName, state)
213}
214
215func ListBlueprintIDsByBiomeState(biomeName string, state string, page int, count int) []uint32 {
216 assertMigrationStateAvailable()
217 assertBiomeName(biomeName)
218 assertBiomeExists(biomeName)
219 assertListPageCount(page, count)
220 return blueprintStore.ListIDsByBiomeState(biomeName, state, page, count)
221}
222
223func assertAdminOrBlueprintOwner(blueprintID uint32, caller address) {
224 if admin.IsAdmin(caller) || blueprintStore.IsOwner(blueprintID, caller) {
225 return
226 }
227 panic("caller must be admin or blueprint owner to update blueprint " + formatBlueprintID(blueprintID))
228}
229
230func assertBiomeExists(biomeName string) {
231 if !personal_world.HasBiomeInfo(biomeName) {
232 panic("unknown biome")
233 }
234}
235
236func send(cur realm, to address, amount int64) {
237 if amount <= 0 {
238 panic("amount must be greater than 0")
239 }
240 bnk := banker.NewBanker(banker.BankerTypeRealmSend, cur)
241 realmAddr := cur.Address()
242 coins := chain.Coins{chain.Coin{"ugnot", amount}}
243 bnk.SendCoins(realmAddr, to, coins)
244}
245
246func formatBlueprintID(blueprintID uint32) string {
247 return strconv.FormatUint(uint64(blueprintID), 10)
248}