Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}