banker_coins_payment_canonical_filetest.gno
2.72 Kb · 82 lines
1// PKGPATH: gno.land/r/treasury/main
2
3package main
4
5import (
6 "chain"
7
8 "gno.land/p/nt/treasury/v0"
9)
10
11// foreign satisfies Payment without being one of treasury's own impls: a
12// BankerID that names a registered banker, and a String() saying whatever
13// its realm likes. No Banker will process it, because Banker.Send
14// type-asserts on the concrete type.
15type foreign struct{}
16
17func (foreign) BankerID() string { return "Coins" }
18
19func (foreign) String() string { return "42ugnot to g1nobody" }
20
21var destAddr = chain.PackageAddress("gno.land/r/dest/main")
22
23func main(cur realm) {
24 // A hand-built set with duplicate denoms is joined, so String() renders
25 // the amount the bank keeper will actually debit rather than "5ugnot,10ugnot".
26 dup := chain.Coins{
27 chain.Coin{Denom: "ugnot", Amount: 5},
28 chain.Coin{Denom: "ugnot", Amount: 10},
29 }
30 println("duplicate denoms joined:", treasury.NewCoinsPayment(dup, destAddr).String())
31
32 // An unsorted set is sorted, for the same reason: std.Coins.validate
33 // rejects "coins not sorted" at execution, after the vote.
34 unsorted := chain.Coins{
35 chain.Coin{Denom: "zzz", Amount: 1},
36 chain.Coin{Denom: "aaa", Amount: 2},
37 }
38 println("unsorted set sorted:", treasury.NewCoinsPayment(unsorted, destAddr).String())
39
40 // A non-positive amount is refused at construction, not at execution.
41 println("negative amount:", mustPanic(func() {
42 treasury.NewCoinsPayment(chain.Coins{chain.Coin{Denom: "ugnot", Amount: -5}}, destAddr)
43 }))
44
45 // Joining can produce a non-positive amount the caller never wrote.
46 println("cancels to negative:", mustPanic(func() {
47 treasury.NewCoinsPayment(chain.Coins{
48 chain.Coin{Denom: "ugnot", Amount: 5},
49 chain.Coin{Denom: "ugnot", Amount: -10},
50 }, destAddr)
51 }))
52
53 // The canonical impls are recognised; a foreign one is not.
54 println("coins payment canonical:", treasury.IsCanonicalPayment(
55 treasury.NewCoinsPayment(chain.NewCoins(chain.NewCoin("ugnot", 1)), destAddr)))
56 println("grc20 payment canonical:", treasury.IsCanonicalPayment(
57 treasury.NewGRC20Payment("TOK", 1, destAddr)))
58 println("foreign payment canonical:", treasury.IsCanonicalPayment(foreign{}))
59}
60
61func mustPanic(fn func()) (msg string) {
62 defer func() {
63 if r := recover(); r != nil {
64 if s, ok := r.(string); ok {
65 msg = s
66 return
67 }
68 msg = "rejected"
69 }
70 }()
71 fn()
72 return "NOT REJECTED"
73}
74
75// Output:
76// duplicate denoms joined: 15ugnot to g1fs92ep7z5vtrp26d767ag3zztsd6wqn9rew4ve
77// unsorted set sorted: 2aaa,1zzz to g1fs92ep7z5vtrp26d767ag3zztsd6wqn9rew4ve
78// negative amount: coins payment amounts must be positive, got -5ugnot
79// cancels to negative: coins payment amounts must be positive, got -5ugnot
80// coins payment canonical: true
81// grc20 payment canonical: true
82// foreign payment canonical: false