govdao.gno
4.02 Kb · 110 lines
1package sugarproxy
2
3import (
4 "strconv"
5
6 "gno.land/r/gov/dao"
7)
8
9// GovDAO's powers over sugar proxy, the last word over everything. Each Propose* below makes a GovDAO proposal
10// request; a GovDAO member submits it (dao.MustCreateProposal), members vote, and when it executes, GovDAO's
11// executor calls the sealed callback, which only r/gov/dao can do. A callback checks the state again (it may have
12// changed since the proposal was made) and returns an error rather than panicking, so a stale proposal fails
13// cleanly instead of sticking.
14
15// ProposeAdd adds an item at once, with no veto window: GovDAO is the veto.
16func ProposeAdd(cur realm, payload string) dao.ProposalRequest {
17 if _, _, err := parse(payload); err != nil {
18 panic(err.Error())
19 }
20 cb := func(cur realm) error {
21 _, err := add(payload, "govdao")
22 return err
23 }
24 return dao.NewProposalRequest("sugar proxy: add "+payload, "Adds `"+payload+"` to sugar proxy's rules, counting at once.",
25 dao.NewSimpleExecutor(0, cur, cb, ""))
26}
27
28// ProposeVeto vetoes an item still in its veto window.
29func ProposeVeto(cur realm, id int) dao.ProposalRequest {
30 cb := func(cur realm) error { return end(id, true, "govdao") }
31 return dao.NewProposalRequest("sugar proxy: veto item "+strconv.Itoa(id), describeItem(id)+" GovDAO vetoes it.",
32 dao.NewSimpleExecutor(0, cur, cb, ""))
33}
34
35// ProposeRemove removes an item at once.
36func ProposeRemove(cur realm, id int) dao.ProposalRequest {
37 cb := func(cur realm) error { return end(id, false, "govdao") }
38 return dao.NewProposalRequest("sugar proxy: remove item "+strconv.Itoa(id), describeItem(id)+" GovDAO removes it.",
39 dao.NewSimpleExecutor(0, cur, cb, ""))
40}
41
42// ProposePause pauses sugar proxy (on) or resumes it: while paused, apps carry nothing and nothing new is added
43// except by GovDAO.
44func ProposePause(cur realm, on bool) dao.ProposalRequest {
45 cb := func(cur realm) error {
46 setPaused(on, "govdao")
47 return nil
48 }
49 what := "resume"
50 if on {
51 what = "pause"
52 }
53 return dao.NewProposalRequest("sugar proxy: "+what, "GovDAO "+what+"s sugar proxy.", dao.NewSimpleExecutor(0, cur, cb, ""))
54}
55
56// ProposeDelegate names the realm that may add and remove sites ("" for none).
57func ProposeDelegate(cur realm, path string) dao.ProposalRequest {
58 cb := func(cur realm) error {
59 delegate = path
60 publish()
61 return nil
62 }
63 return dao.NewProposalRequest("sugar proxy: delegate sites to "+path, "Names `"+path+"` as the realm that may add and "+
64 "remove sugar proxy's sites (each waiting out the veto window). Empty names none.", dao.NewSimpleExecutor(0, cur, cb, ""))
65}
66
67// ProposeGuardian names the address that may veto and pause ("" for none).
68func ProposeGuardian(cur realm, a address) dao.ProposalRequest {
69 if a != "" && !a.IsValid() {
70 panic("not an address")
71 }
72 cb := func(cur realm) error {
73 guardian = a
74 return nil
75 }
76 return dao.NewProposalRequest("sugar proxy: guardian "+a.String(), "Names "+a.String()+" sugar proxy's guardian, who may "+
77 "veto items in their window and pause, never approve. Empty names none.", dao.NewSimpleExecutor(0, cur, cb, ""))
78}
79
80// ProposeVetoWindow sets how long an added item of a kind waits before it counts, in seconds (one hour to 60 days).
81func ProposeVetoWindow(cur realm, kind string, seconds int64) dao.ProposalRequest {
82 if _, ok := vetoWin[kind]; !ok || seconds < 3600 || seconds > 60*86400 {
83 panic("a kind's veto window is 3600 to 5184000 seconds")
84 }
85 cb := func(cur realm) error {
86 vetoWin[kind] = seconds
87 return nil
88 }
89 return dao.NewProposalRequest("sugar proxy: "+kind+" veto window "+strconv.FormatInt(seconds, 10)+" s", "Sets the veto window "+
90 "for a new "+kind+" to "+strconv.FormatInt(seconds, 10)+" seconds.", dao.NewSimpleExecutor(0, cur, cb, ""))
91}
92
93func describeItem(id int) string {
94 it := find(id)
95 if it == nil {
96 return "Item " + strconv.Itoa(id) + " (none such yet)."
97 }
98 return "Item " + strconv.Itoa(id) + ": " + it.Kind + " `" + joinFields(it.Fields) + "`, " + it.State + "."
99}
100
101func joinFields(f []string) string {
102 out := ""
103 for i, x := range f {
104 if i > 0 {
105 out += "|"
106 }
107 out += x
108 }
109 return out
110}