Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

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