valopers_test.gno
13.28 Kb ยท 525 lines
1package valopers
2
3import (
4 "std"
5 "strings"
6 "testing"
7
8 "gno.land/p/demo/avl"
9 "gno.land/p/demo/ownable/exts/authorizable"
10 "gno.land/p/demo/testutils"
11 "gno.land/p/demo/uassert"
12 "gno.land/p/demo/ufmt"
13)
14
15func validValidatorInfo(t *testing.T) struct {
16 Moniker string
17 Description string
18 Address std.Address
19 PubKey string
20} {
21 t.Helper()
22
23 return struct {
24 Moniker string
25 Description string
26 Address std.Address
27 PubKey string
28 }{
29 Moniker: "test-1",
30 Description: "test-1's description",
31 Address: std.Address("g1sp8v98h2gadm5jggtzz9w5ksexqn68ympsd68h"),
32 PubKey: "gpub1pggj7ard9eg82cjtv4u52epjx56nzwgjyg9zqwpdwpd0f9fvqla089ndw5g9hcsufad77fml2vlu73fk8q8sh8v72cza5p",
33 }
34}
35
36func TestValopers_Register(t *testing.T) {
37 t.Run("already a valoper", func(t *testing.T) {
38 // Clear the set for the test
39 valopers = avl.NewTree()
40
41 info := validValidatorInfo(t)
42
43 v := Valoper{
44 Moniker: info.Moniker,
45 Description: info.Description,
46 Address: info.Address,
47 PubKey: info.PubKey,
48 KeepRunning: true,
49 }
50
51 // Add the valoper
52 valopers.Set(v.Address.String(), v)
53
54 // Send coins
55 testing.SetOriginSend(std.Coins{minFee})
56
57 uassert.PanicsWithMessage(t, ErrValoperExists.Error(), func() {
58 Register(info.Moniker, info.Description, info.Address, info.PubKey)
59 })
60 })
61
62 t.Run("no coins deposited", func(t *testing.T) {
63 // Clear the set for the test
64 valopers = avl.NewTree()
65
66 info := validValidatorInfo(t)
67
68 // Send no coins
69 testing.SetOriginSend(std.Coins{std.NewCoin("ugnot", 0)})
70
71 uassert.PanicsWithMessage(t, ufmt.Sprintf("payment must not be less than %d%s", minFee.Amount, minFee.Denom), func() {
72 Register(info.Moniker, info.Description, info.Address, info.PubKey)
73 })
74 })
75
76 t.Run("insufficient coins amount deposited", func(t *testing.T) {
77 // Clear the set for the test
78 valopers = avl.NewTree()
79
80 info := validValidatorInfo(t)
81
82 // Send invalid coins
83 testing.SetOriginSend(std.Coins{std.NewCoin("ugnot", minFee.Amount-1)})
84
85 uassert.PanicsWithMessage(t, ufmt.Sprintf("payment must not be less than %d%s", minFee.Amount, minFee.Denom), func() {
86 Register(info.Moniker, info.Description, info.Address, info.PubKey)
87 })
88 })
89
90 t.Run("coin amount deposited is not ugnot", func(t *testing.T) {
91 // Clear the set for the test
92 valopers = avl.NewTree()
93
94 info := validValidatorInfo(t)
95
96 // Send invalid coins
97 testing.SetOriginSend(std.Coins{std.NewCoin("gnogno", minFee.Amount)})
98
99 uassert.PanicsWithMessage(t, "incompatible coin denominations: gnogno, ugnot", func() {
100 Register(info.Moniker, info.Description, info.Address, info.PubKey)
101 })
102 })
103
104 t.Run("successful registration", func(t *testing.T) {
105 // Clear the set for the test
106 valopers = avl.NewTree()
107
108 info := validValidatorInfo(t)
109
110 // Send coins
111 testing.SetOriginSend(std.Coins{minFee})
112
113 uassert.NotPanics(t, func() {
114 Register(info.Moniker, info.Description, info.Address, info.PubKey)
115 })
116
117 uassert.NotPanics(t, func() {
118 valoper := GetByAddr(info.Address)
119
120 uassert.Equal(t, info.Moniker, valoper.Moniker)
121 uassert.Equal(t, info.Description, valoper.Description)
122 uassert.Equal(t, info.Address, valoper.Address)
123 uassert.Equal(t, info.PubKey, valoper.PubKey)
124 uassert.Equal(t, true, valoper.KeepRunning)
125 })
126 })
127}
128
129func TestValopers_UpdateAuthMembers(t *testing.T) {
130 test1Address := testutils.TestAddress("test1")
131 test2Address := testutils.TestAddress("test2")
132
133 t.Run("unauthorized member adds member", func(t *testing.T) {
134 // Clear the set for the test
135 valopers = avl.NewTree()
136
137 info := validValidatorInfo(t)
138
139 // Send coins
140 testing.SetOriginSend(std.Coins{minFee})
141
142 testing.SetRealm(std.NewUserRealm(test1Address))
143 testing.SetOriginCaller(test1Address) // TODO(bug, issue #2371): should not be needed
144
145 // Add the valoper
146 uassert.NotPanics(t, func() {
147 Register(info.Moniker, info.Description, info.Address, info.PubKey)
148 })
149
150 testing.SetRealm(std.NewUserRealm(info.Address))
151 testing.SetOriginCaller(info.Address) // TODO(bug, issue #2371): should not be needed
152
153 // try to add member without being authorized
154 uassert.PanicsWithMessage(t, authorizable.ErrNotSuperuser.Error(), func() {
155 AddToAuthList(info.Address, test2Address)
156 })
157 })
158
159 t.Run("unauthorized member deletes member", func(t *testing.T) {
160 // Clear the set for the test
161 valopers = avl.NewTree()
162
163 info := validValidatorInfo(t)
164
165 // Send coins
166 testing.SetOriginSend(std.Coins{minFee})
167
168 testing.SetRealm(std.NewUserRealm(test1Address))
169 testing.SetOriginCaller(test1Address) // TODO(bug, issue #2371): should not be needed
170
171 // Add the valoper
172 uassert.NotPanics(t, func() {
173 Register(info.Moniker, info.Description, info.Address, info.PubKey)
174 })
175
176 uassert.NotPanics(t, func() {
177 AddToAuthList(info.Address, test2Address)
178 })
179
180 testing.SetRealm(std.NewUserRealm(info.Address))
181 testing.SetOriginCaller(info.Address) // TODO(bug, issue #2371): should not be needed
182
183 // try to add member without being authorized
184 uassert.PanicsWithMessage(t, authorizable.ErrNotSuperuser.Error(), func() {
185 DeleteFromAuthList(info.Address, test2Address)
186 })
187 })
188
189 t.Run("authorized member adds member", func(t *testing.T) {
190 // Clear the set for the test
191 valopers = avl.NewTree()
192
193 info := validValidatorInfo(t)
194
195 // Send coins
196 testing.SetOriginSend(std.Coins{minFee})
197
198 testing.SetRealm(std.NewUserRealm(test1Address))
199 testing.SetOriginCaller(test1Address) // TODO(bug, issue #2371): should not be needed
200
201 // Add the valoper
202 uassert.NotPanics(t, func() {
203 Register(info.Moniker, info.Description, info.Address, info.PubKey)
204 })
205
206 uassert.NotPanics(t, func() {
207 AddToAuthList(info.Address, test2Address)
208 })
209
210 testing.SetRealm(std.NewUserRealm(test2Address))
211 testing.SetOriginCaller(test2Address) // TODO(bug, issue #2371): should not be needed
212
213 newMoniker := "new moniker"
214 // Update the valoper
215 uassert.NotPanics(t, func() {
216 UpdateMoniker(info.Address, newMoniker)
217 })
218
219 uassert.NotPanics(t, func() {
220 valoper := GetByAddr(info.Address)
221 uassert.Equal(t, newMoniker, valoper.Moniker)
222 })
223 })
224}
225
226func TestValopers_UpdateMoniker(t *testing.T) {
227 test1Address := testutils.TestAddress("test1")
228 test2Address := testutils.TestAddress("test2")
229
230 t.Run("non-existing valoper", func(t *testing.T) {
231 // Clear the set for the test
232 valopers = avl.NewTree()
233
234 info := validValidatorInfo(t)
235
236 // Update the valoper
237 uassert.PanicsWithMessage(t, ErrValoperMissing.Error(), func() {
238 UpdateMoniker(info.Address, "new moniker")
239 })
240 })
241
242 t.Run("invalid caller", func(t *testing.T) {
243 // Set the origin caller
244 testing.SetOriginCaller(test1Address)
245
246 // Clear the set for the test
247 valopers = avl.NewTree()
248
249 info := validValidatorInfo(t)
250
251 // Send coins
252 testing.SetOriginSend(std.Coins{minFee})
253
254 // Add the valoper
255 uassert.NotPanics(t, func() {
256 Register(info.Moniker, info.Description, info.Address, info.PubKey)
257 })
258
259 // Change the origin caller
260 testing.SetOriginCaller(test2Address)
261
262 // Update the valoper
263 uassert.PanicsWithMessage(t, authorizable.ErrNotInAuthList.Error(), func() {
264 UpdateMoniker(info.Address, "new moniker")
265 })
266 })
267
268 t.Run("invalid moniker", func(t *testing.T) {
269 invalidMonikers := []string{
270 "", // Empty
271 " ", // Whitespace
272 "a", // Too short
273 "a very long moniker that is longer than 32 characters", // Too long
274 "!@#$%^&*()+{}|:<>?/.,;'", // Invalid characters
275 " space in front",
276 "space in back ",
277 }
278
279 // Clear the set for the test
280 valopers = avl.NewTree()
281
282 info := validValidatorInfo(t)
283
284 // Send coins
285 testing.SetOriginSend(std.Coins{minFee})
286
287 // Add the valoper
288 uassert.NotPanics(t, func() {
289 Register(info.Moniker, info.Description, info.Address, info.PubKey)
290 })
291
292 for _, invalidMoniker := range invalidMonikers {
293 // Update the valoper
294 uassert.PanicsWithMessage(t, ErrInvalidMoniker.Error(), func() {
295 UpdateMoniker(info.Address, invalidMoniker)
296 })
297 }
298 })
299
300 t.Run("too long moniker", func(t *testing.T) {
301 // Clear the set for the test
302 valopers = avl.NewTree()
303
304 info := validValidatorInfo(t)
305
306 // Send coins
307 testing.SetOriginSend(std.Coins{minFee})
308
309 // Add the valoper
310 uassert.NotPanics(t, func() {
311 Register(info.Moniker, info.Description, info.Address, info.PubKey)
312 })
313
314 // Update the valoper
315 uassert.PanicsWithMessage(t, ErrInvalidMoniker.Error(), func() {
316 UpdateMoniker(info.Address, strings.Repeat("a", MonikerMaxLength+1))
317 })
318 })
319
320 t.Run("successful update", func(t *testing.T) {
321 // Clear the set for the test
322 valopers = avl.NewTree()
323
324 info := validValidatorInfo(t)
325
326 // Send coins
327 testing.SetOriginSend(std.Coins{minFee})
328
329 // Add the valoper
330 uassert.NotPanics(t, func() {
331 Register(info.Moniker, info.Description, info.Address, info.PubKey)
332 })
333
334 newMoniker := "new moniker"
335 // Update the valoper
336 uassert.NotPanics(t, func() {
337 UpdateMoniker(info.Address, newMoniker)
338 })
339
340 // Make sure the valoper is updated
341 uassert.NotPanics(t, func() {
342 valoper := GetByAddr(info.Address)
343
344 uassert.Equal(t, newMoniker, valoper.Moniker)
345 })
346 })
347}
348
349func TestValopers_UpdateDescription(t *testing.T) {
350 test1Address := testutils.TestAddress("test1")
351 test2Address := testutils.TestAddress("test2")
352
353 t.Run("non-existing valoper", func(t *testing.T) {
354 // Clear the set for the test
355 valopers = avl.NewTree()
356
357 // Update the valoper
358 uassert.PanicsWithMessage(t, ErrValoperMissing.Error(), func() {
359 UpdateDescription(validValidatorInfo(t).Address, "new description")
360 })
361 })
362
363 t.Run("invalid caller", func(t *testing.T) {
364 // Set the origin caller
365 testing.SetOriginCaller(test1Address)
366
367 info := validValidatorInfo(t)
368
369 // Clear the set for the test
370 valopers = avl.NewTree()
371
372 // Send coins
373 testing.SetOriginSend(std.Coins{minFee})
374
375 // Add the valoper
376 uassert.NotPanics(t, func() {
377 Register(info.Moniker, info.Description, info.Address, info.PubKey)
378 })
379
380 // Change the origin caller
381 testing.SetOriginCaller(test2Address)
382
383 // Update the valoper
384 uassert.PanicsWithMessage(t, authorizable.ErrNotInAuthList.Error(), func() {
385 UpdateDescription(info.Address, "new description")
386 })
387 })
388
389 t.Run("empty description", func(t *testing.T) {
390 // Clear the set for the test
391 valopers = avl.NewTree()
392
393 info := validValidatorInfo(t)
394
395 // Send coins
396 testing.SetOriginSend(std.Coins{minFee})
397
398 // Add the valoper
399 uassert.NotPanics(t, func() {
400 Register(info.Moniker, info.Description, info.Address, info.PubKey)
401 })
402
403 emptyDescription := ""
404 // Update the valoper
405 uassert.PanicsWithMessage(t, ErrInvalidDescription.Error(), func() {
406 UpdateDescription(info.Address, emptyDescription)
407 })
408 })
409
410 t.Run("too long description", func(t *testing.T) {
411 // Clear the set for the test
412 valopers = avl.NewTree()
413
414 info := validValidatorInfo(t)
415
416 // Send coins
417 testing.SetOriginSend(std.Coins{minFee})
418
419 // Add the valoper
420 uassert.NotPanics(t, func() {
421 Register(info.Moniker, info.Description, info.Address, info.PubKey)
422 })
423
424 // Update the valoper
425 uassert.PanicsWithMessage(t, ErrInvalidDescription.Error(), func() {
426 UpdateDescription(info.Address, strings.Repeat("a", DescriptionMaxLength+1))
427 })
428 })
429
430 t.Run("successful update", func(t *testing.T) {
431 // Clear the set for the test
432 valopers = avl.NewTree()
433
434 info := validValidatorInfo(t)
435
436 // Send coins
437 testing.SetOriginSend(std.Coins{minFee})
438
439 // Add the valoper
440 uassert.NotPanics(t, func() {
441 Register(info.Moniker, info.Description, info.Address, info.PubKey)
442 })
443
444 newDescription := "new description"
445 // Update the valoper
446 uassert.NotPanics(t, func() {
447 UpdateDescription(info.Address, newDescription)
448 })
449
450 // Make sure the valoper is updated
451 uassert.NotPanics(t, func() {
452 valoper := GetByAddr(info.Address)
453
454 uassert.Equal(t, newDescription, valoper.Description)
455 })
456 })
457}
458
459func TestValopers_UpdateKeepRunning(t *testing.T) {
460 test1Address := testutils.TestAddress("test1")
461 test2Address := testutils.TestAddress("test2")
462
463 t.Run("non-existing valoper", func(t *testing.T) {
464 // Clear the set for the test
465 valopers = avl.NewTree()
466
467 // Update the valoper
468 uassert.PanicsWithMessage(t, ErrValoperMissing.Error(), func() {
469 UpdateKeepRunning(validValidatorInfo(t).Address, false)
470 })
471 })
472
473 t.Run("invalid caller", func(t *testing.T) {
474 // Set the origin caller
475 testing.SetOriginCaller(test1Address)
476
477 // Clear the set for the test
478 valopers = avl.NewTree()
479
480 info := validValidatorInfo(t)
481
482 // Send coins
483 testing.SetOriginSend(std.Coins{minFee})
484
485 // Add the valoper
486 uassert.NotPanics(t, func() {
487 Register(info.Moniker, info.Description, info.Address, info.PubKey)
488 })
489
490 // Change the origin caller
491 testing.SetOriginCaller(test2Address)
492
493 // Update the valoper
494 uassert.PanicsWithMessage(t, authorizable.ErrNotInAuthList.Error(), func() {
495 UpdateKeepRunning(info.Address, false)
496 })
497 })
498
499 t.Run("successful update", func(t *testing.T) {
500 // Clear the set for the test
501 valopers = avl.NewTree()
502
503 info := validValidatorInfo(t)
504
505 // Send coins
506 testing.SetOriginSend(std.Coins{minFee})
507
508 // Add the valoper
509 uassert.NotPanics(t, func() {
510 Register(info.Moniker, info.Description, info.Address, info.PubKey)
511 })
512
513 // Update the valoper
514 uassert.NotPanics(t, func() {
515 UpdateKeepRunning(info.Address, false)
516 })
517
518 // Make sure the valoper is updated
519 uassert.NotPanics(t, func() {
520 valoper := GetByAddr(info.Address)
521
522 uassert.Equal(t, false, valoper.KeepRunning)
523 })
524 })
525}