instance.gno
4.08 Kb ยท 163 lines
1package v1
2
3import (
4 "gno.land/p/nt/avl"
5 "gno.land/p/nt/ufmt"
6 "gno.land/r/gnoswap/gov/governance"
7)
8
9type governanceV1 struct {
10 store governance.IGovernanceStore
11 stakerAccessor governance.GovStakerAccessor
12}
13
14func NewGovernanceV1(
15 governanceStore governance.IGovernanceStore,
16 stakerAccessor governance.GovStakerAccessor,
17) governance.IGovernance {
18 return &governanceV1{
19 store: governanceStore,
20 stakerAccessor: stakerAccessor,
21 }
22}
23
24// Config version methods
25func (g *governanceV1) getCurrentConfigVersion() int64 {
26 return g.store.GetConfigCounter().Get()
27}
28
29func (g *governanceV1) nextConfigVersion() int64 {
30 return g.store.GetConfigCounter().Next()
31}
32
33// Proposal ID methods
34func (g *governanceV1) getCurrentProposalID() int64 {
35 return g.store.GetProposalCounter().Get()
36}
37
38func (g *governanceV1) nextProposalID() int64 {
39 return g.store.GetProposalCounter().Next()
40}
41
42// Config methods
43func (g *governanceV1) getConfig(version int64) (governance.Config, bool) {
44 return g.store.GetConfig(version)
45}
46
47func (g *governanceV1) setConfig(version int64, config governance.Config) error {
48 return g.store.SetConfig(version, config)
49}
50
51func (g *governanceV1) getCurrentConfig() (governance.Config, bool) {
52 return g.getConfig(g.getCurrentConfigVersion())
53}
54
55// Proposal methods
56func (g *governanceV1) getProposal(id int64) (*governance.Proposal, bool) {
57 proposal, exists := g.store.GetProposal(id)
58 if !exists {
59 return nil, false
60 }
61
62 return proposal, true
63}
64
65func (g *governanceV1) addProposal(proposal *governance.Proposal) bool {
66 // Set the proposal (ID already set in proposal)
67 err := g.store.SetProposal(proposal.ID(), proposal)
68 if err != nil {
69 return false
70 }
71
72 // Add to user proposals
73 err = g.store.AddUserProposal(proposal.Proposer().String(), proposal.ID())
74 if err != nil {
75 return false
76 }
77
78 return true
79}
80
81// User proposals methods
82func (g *governanceV1) getUserProposals(user string) []*governance.Proposal {
83 proposalIDs, exists := g.store.GetUserProposalIDs(user)
84 if !exists {
85 return []*governance.Proposal{}
86 }
87
88 proposals := make([]*governance.Proposal, 0)
89
90 for _, id := range proposalIDs {
91 proposal, exists := g.store.GetProposal(id)
92 if !exists {
93 continue
94 }
95
96 proposals = append(proposals, proposal)
97 }
98
99 return proposals
100}
101
102func (g *governanceV1) hasActiveProposal(proposerAddress address, current int64) bool {
103 proposals := g.getUserProposals(proposerAddress.String())
104
105 return len(proposals) > 0
106}
107
108// Remove inactive user proposals
109// This function is used to remove inactive proposals from the user proposals list.
110// It is used to clean up user's active proposal list when creating a new proposal.
111func (g *governanceV1) removeInactiveUserProposals(proposerAddress address, current int64) error {
112 proposals := g.getUserProposals(proposerAddress.String())
113
114 for _, proposal := range proposals {
115 proposalResolver := NewProposalResolver(proposal)
116
117 if !proposalResolver.IsActive(current) {
118 err := g.store.RemoveUserProposal(proposerAddress.String(), proposal.ID())
119 if err != nil {
120 return err
121 }
122 }
123 }
124
125 return nil
126}
127
128// Proposal voting info methods
129func (g *governanceV1) getProposalUserVotingInfos(proposalID int64) (*avl.Tree, bool) {
130 return g.store.GetProposalVotingInfos(proposalID)
131}
132
133func (g *governanceV1) updateProposalUserVotes(proposal *governance.Proposal, userVotingInfos *avl.Tree) error {
134 return g.store.SetProposalVotingInfos(proposal.ID(), userVotingInfos)
135}
136
137// Helper methods for API
138func (g *governanceV1) mustGetProposal(id int64) *governance.Proposal {
139 proposal, exists := g.getProposal(id)
140 if !exists {
141 panic(makeErrorWithDetails(errProposalNotFound, ufmt.Sprintf("proposal(%d) not found", id)))
142 }
143 return proposal
144}
145
146func (g *governanceV1) getProposalUserVotingInfo(proposalID int64, addr address) (*governance.VotingInfo, bool) {
147 votingInfosTree, exists := g.getProposalUserVotingInfos(proposalID)
148 if !exists {
149 return nil, false
150 }
151
152 votingInfoRaw, exists := votingInfosTree.Get(addr.String())
153 if !exists {
154 return nil, false
155 }
156
157 votingInfo, ok := votingInfoRaw.(*governance.VotingInfo)
158 if !ok {
159 return nil, false
160 }
161
162 return votingInfo, true
163}