params.gno
5.93 Kb · 148 lines
1// Package params provides functions for creating parameter executors that
2// interface with the Params Keeper.
3//
4// This package enables setting various parameter types (such as strings,
5// integers, booleans, and byte slices) through the GovDAO proposal mechanism.
6// Each function returns an executor that, when called, sets the specified
7// parameter in the Params Keeper.
8//
9// The executors are designed to be used within governance proposals to modify
10// parameters dynamically. The integration with the GovDAO allows for parameter
11// changes to be proposed and executed in a controlled manner, ensuring that
12// modifications are subject to governance processes.
13//
14// Example usage:
15//
16// // This executor can be used in a governance proposal to set the parameter.
17// pr := params.NewSysParamStringPropExecutor("bank", "p", "restricted_denoms")
18package params
19
20import (
21 "chain"
22 prms "sys/params"
23
24 "gno.land/r/gov/dao"
25)
26
27// this is only used for emitting events.
28func syskey(module, submodule, name string) string {
29 return module + ":" + submodule + ":" + name
30}
31
32// assertNotValsetKey rejects governance proposals that target the
33// node:valset:* key family. Those keys are reserved for the realm-side
34// gate in r/sys/params/valset.gno (SetValsetProposal) which checks
35// the immediate caller is gno.land/r/sys/validators/v0. Without this
36// guard, a generic NewSysParam*PropRequest("node","valset",...) would
37// let any GovDAO supermajority bypass the v0 authorization and write
38// validator-set state directly.
39func assertNotValsetKey(module, submodule string) {
40 if module == "node" && submodule == "valset" {
41 panic("node:valset:* is reserved for r/sys/validators/v0; use it instead of the generic factory")
42 }
43}
44
45// assertNotRunSubmittersKey rejects generic proposals that target
46// vm:p:run_submitters. Same shape as assertNotValsetKey above, and the same
47// reason: the key has a realm-side gate the generic factory would walk past.
48//
49// An empty run_submitters means the MsgRun gate is OFF. So a non-empty list is
50// the chain deciding who may run code, and a list that names nobody able to
51// create a GovDAO proposal cannot be changed back -- creating a proposal needs
52// MsgRun, because a ProposalRequest carries an Executor that MsgCall cannot
53// build from string arguments. The dedicated ProposeSetRunSubmitters in
54// run_submitters.gno refuses that list at proposal-creation time, where a human
55// can still act on the refusal.
56//
57// Reserving the key rather than adding the check to all nine factories keeps
58// the number of ways to write this parameter at one.
59func assertNotRunSubmittersKey(module, submodule, name string) {
60 if module == "vm" && submodule == "p" && name == runSubmittersKey {
61 panic(runSubmittersKey + " is reserved for ProposeSetRunSubmitters in this realm; " +
62 "use it instead of the generic factory")
63 }
64}
65
66func NewSysParamStringPropRequest(cur realm, module, submodule, name, value string) dao.ProposalRequest {
67 return newPropRequest(cur, module, submodule, name,
68 func() { prms.SetSysParamString(module, submodule, name, value) },
69 "",
70 )
71}
72
73func NewSysParamInt64PropRequest(cur realm, module, submodule, name string, value int64) dao.ProposalRequest {
74 return newPropRequest(cur, module, submodule, name,
75 func() { prms.SetSysParamInt64(module, submodule, name, value) },
76 "",
77 )
78}
79
80func NewSysParamUint64PropRequest(cur realm, module, submodule, name string, value uint64) dao.ProposalRequest {
81 return newPropRequest(cur, module, submodule, name,
82 func() { prms.SetSysParamUint64(module, submodule, name, value) },
83 "",
84 )
85}
86
87func NewSysParamBoolPropRequest(cur realm, module, submodule, name string, value bool) dao.ProposalRequest {
88 return newPropRequest(cur, module, submodule, name,
89 func() { prms.SetSysParamBool(module, submodule, name, value) },
90 "",
91 )
92}
93
94func NewSysParamBytesPropRequest(cur realm, module, submodule, name string, value []byte) dao.ProposalRequest {
95 return newPropRequest(cur, module, submodule, name,
96 func() { prms.SetSysParamBytes(module, submodule, name, value) },
97 "",
98 )
99}
100
101func NewSysParamStringsPropRequest(cur realm, module, submodule, name string, value []string) dao.ProposalRequest {
102 return newPropRequest(cur, module, submodule, name,
103 func() { prms.SetSysParamStrings(module, submodule, name, value) },
104 "",
105 )
106}
107
108func NewSysParamStringsPropRequestWithTitle(cur realm, module, submodule, name, title string, value []string) dao.ProposalRequest {
109 return newPropRequest(cur, module, submodule, name,
110 func() { prms.SetSysParamStrings(module, submodule, name, value) },
111 title,
112 )
113}
114func NewSysParamStringsPropRequestAddWithTitle(cur realm, module, submodule, name, title string, value []string) dao.ProposalRequest {
115 return newPropRequest(cur, module, submodule, name,
116 func() { prms.UpdateSysParamStrings(module, submodule, name, value, true) },
117 title,
118 )
119}
120func NewSysParamStringsPropRequestRemoveWithTitle(cur realm, module, submodule, name, title string, value []string) dao.ProposalRequest {
121 return newPropRequest(cur, module, submodule, name,
122 func() { prms.UpdateSysParamStrings(module, submodule, name, value, false) },
123 title,
124 )
125}
126func newPropRequest(cur realm, module, submodule, name string, fn func(), title string) dao.ProposalRequest {
127 // The reserved-key checks live here rather than in each factory. Every
128 // generic factory returns through this one function, so a factory added
129 // later cannot forget them. The dedicated setters for those keys build their
130 // own request and never come here, which is what makes them the exception.
131 assertNotValsetKey(module, submodule)
132 assertNotRunSubmittersKey(module, submodule, name)
133
134 key := syskey(module, submodule, name)
135 callback := func(cur realm) error {
136 fn()
137 chain.Emit("set", "key", key) // TODO document, make const, make consistent. 'k'??
138 return nil
139 }
140
141 if title == "" {
142 title = "Set new sys/params key"
143 }
144
145 e := dao.NewSimpleExecutor(0, cur, callback, "")
146
147 return dao.NewProposalRequest(title, "This proposal wants to add a new key to sys/params: "+key, e)
148}