admin.gno
2.75 Kb · 110 lines
1package users
2
3import (
4 "chain"
5 "chain/runtime"
6
7 "gno.land/p/moul/addrset"
8 "gno.land/p/nt/ufmt/v0"
9
10 "gno.land/r/gov/dao"
11)
12
13const initControllerPath = "gno.land/r/sys/users/init"
14
15var controllers = addrset.Set{} // caller whitelist
16
17func init() {
18 // auto-whitelist the init controller for bootstrapping for testing chain.
19 if chainID := runtime.ChainID(); chainID == "dev" {
20 controllers.Add(chain.PackageAddress(initControllerPath))
21 }
22}
23
24// AddControllerAtGenesis allows adding a controller during chain genesis (height 0).
25// This is mostly useful for testing.
26func AddControllerAtGenesis(_ realm, addr address) {
27 height := runtime.ChainHeight()
28 if height > 0 {
29 panic("AddControllerAtGenesis can only be called at genesis (height 0)")
30 }
31
32 if !addr.IsValid() {
33 panic(ErrInvalidAddress)
34 }
35
36 controllers.Add(addr)
37}
38
39// ProposeNewController allows GovDAO to add a whitelisted caller
40func ProposeNewController(addr address) dao.ProposalRequest {
41 if !addr.IsValid() {
42 panic(ErrInvalidAddress)
43 }
44
45 cb := func(cur realm) error {
46 return addToWhitelist(addr)
47 }
48
49 desc := "This proposal adds " + addr.String() + " to `sys/users` realm's callers whitelist."
50 return dao.NewProposalRequest("Add Whitelisted Caller to \"sys/users\" Realm", desc, dao.NewSimpleExecutor(cb, ""))
51}
52
53// ProposeControllerRemoval allows GovDAO to add a whitelisted caller
54func ProposeControllerRemoval(addr address) dao.ProposalRequest {
55 if !addr.IsValid() {
56 panic(ErrInvalidAddress)
57 }
58
59 cb := func(cur realm) error {
60 return deleteFromWhitelist(addr)
61 }
62
63 desc := "This proposal removes " + addr.String() + " from `sys/users` realm's callers whitelist."
64 return dao.NewProposalRequest("Remove Whitelisted Caller From \"sys/users\" Realm", desc, dao.NewSimpleExecutor(cb, ""))
65}
66
67// ProposeControllerAdditionAndRemoval allows GovDAO to add a new caller and remove an old caller in the same proposal.
68func ProposeControllerAdditionAndRemoval(toAdd, toRemove address) dao.ProposalRequest {
69 if !toAdd.IsValid() || !toRemove.IsValid() {
70 panic(ErrInvalidAddress)
71 }
72
73 cb := func(cur realm) error {
74 err := addToWhitelist(toAdd)
75 if err != nil {
76 return err
77 }
78
79 return deleteFromWhitelist(toRemove)
80 }
81
82 desc := ufmt.Sprint(
83 "This proposal adds %s and removes %s from `sys/users` realm's callers whitelist.",
84 toAdd,
85 toRemove,
86 )
87 return dao.NewProposalRequest("Add and Remove Whitelisted Callers From \"sys/users\" Realm", desc, dao.NewSimpleExecutor(cb, ""))
88}
89
90// Helpers
91
92func deleteFromWhitelist(addr address) error {
93 if !controllers.Has(addr) {
94 return NewErrNotWhitelisted()
95 }
96
97 if ok := controllers.Remove(addr); !ok {
98 return ErrWhitelistRemoveFailed
99 }
100
101 return nil
102}
103
104func addToWhitelist(newCaller address) error {
105 if !controllers.Add(newCaller) {
106 return ErrAlreadyWhitelisted
107 }
108
109 return nil
110}