proposal.gno
7.97 Kb · 274 lines
1package governance
2
3import bptree "gno.land/p/nt/bptree/v0"
4
5// Proposal represents a governance proposal with all its associated data and state.
6// This is the core structure that tracks proposal lifecycle from creation to execution.
7type Proposal struct {
8 id int64 // Unique identifier for the proposal
9 proposer address // The address of the proposer
10 configVersion int64 // The version of the governance config used
11 status *ProposalStatus // Current status and voting information
12 metadata *ProposalMetadata // Title and description
13 data *ProposalData // Type-specific proposal data
14 snapshotTime int64 // Timestamp for voting weight snapshot lookup
15 createdHeight int64 // Block height at creation
16}
17
18// ID returns the unique identifier assigned to the proposal.
19//
20// Returns:
21// - int64: proposal identifier used as its storage key
22func (p *Proposal) ID() int64 {
23 return p.id
24}
25
26// Type returns the proposal's type discriminator from its type-specific data.
27//
28// Returns:
29// - ProposalType: proposal kind, such as text, community-pool spend, or parameter change
30func (p *Proposal) Type() ProposalType {
31 return p.data.ProposalType()
32}
33
34// Title returns the proposal title stored in its metadata.
35//
36// Returns:
37// - string: proposal title
38func (p *Proposal) Title() string {
39 return p.metadata.Title()
40}
41
42// Description returns the proposal description stored in its metadata.
43//
44// Returns:
45// - string: proposal description
46func (p *Proposal) Description() string {
47 return p.metadata.Description()
48}
49
50// Proposer returns the address that created the proposal.
51//
52// Returns:
53// - address: proposal creator's address
54func (p *Proposal) Proposer() address {
55 return p.proposer
56}
57
58// CreatedHeight returns the block height at which the proposal was created.
59//
60// Returns:
61// - int64: proposal creation block height
62func (p *Proposal) CreatedHeight() int64 {
63 return p.createdHeight
64}
65
66// CreatedAt returns the proposal creation timestamp recorded in its schedule.
67//
68// Returns:
69// - int64: proposal creation timestamp
70func (p *Proposal) CreatedAt() int64 {
71 return p.status.schedule.createTime
72}
73
74// VotingYesWeight returns the total weight recorded for "yes" votes.
75//
76// Returns:
77// - int64: current "yes" vote weight
78func (p *Proposal) VotingYesWeight() int64 {
79 return p.status.voteStatus.yea
80}
81
82// VotingNoWeight returns the total weight recorded for "no" votes.
83//
84// Returns:
85// - int64: current "no" vote weight
86func (p *Proposal) VotingNoWeight() int64 {
87 return p.status.voteStatus.nay
88}
89
90// VotingQuorumAmount returns the minimum total vote weight required to pass.
91//
92// Returns:
93// - int64: quorum vote weight required by this proposal's configuration
94func (p *Proposal) VotingQuorumAmount() int64 {
95 return p.status.voteStatus.quorumAmount
96}
97
98// VotingMaxWeight returns the maximum voting weight recorded for this proposal.
99//
100// Returns:
101// - int64: maximum voting weight used for the proposal's quorum calculation
102func (p *Proposal) VotingMaxWeight() int64 {
103 return p.status.voteStatus.maxVotingWeight
104}
105
106// ConfigVersion returns the governance configuration version used by the proposal.
107//
108// Returns:
109// - int64: configuration version captured when the proposal was created
110func (p *Proposal) ConfigVersion() int64 {
111 return p.configVersion
112}
113
114// SnapshotTime returns the timestamp used to look up historical voting weight.
115//
116// Returns:
117// - int64: voting-weight snapshot timestamp
118func (p *Proposal) SnapshotTime() int64 {
119 return p.snapshotTime
120}
121
122// Data returns the proposal's type-specific data.
123//
124// Returns:
125// - *ProposalData: type-specific proposal data stored on the proposal
126func (p *Proposal) Data() *ProposalData {
127 return p.data
128}
129
130// Status returns the proposal's schedule, vote, and action status.
131//
132// Returns:
133// - *ProposalStatus: mutable aggregate status associated with the proposal
134func (p *Proposal) Status() *ProposalStatus {
135 return p.status
136}
137
138// Metadata returns the proposal's title and description metadata.
139//
140// Returns:
141// - *ProposalMetadata: metadata stored on the proposal
142func (p *Proposal) Metadata() *ProposalMetadata {
143 return p.metadata
144}
145
146// IsTextType reports whether the proposal is a text proposal.
147//
148// Returns:
149// - bool: true when the proposal type is Text
150func (p *Proposal) IsTextType() bool {
151 return p.Type() == Text
152}
153
154// IsCommunityPoolSpendType reports whether the proposal spends community-pool funds.
155//
156// Returns:
157// - bool: true when the proposal type is CommunityPoolSpend
158func (p *Proposal) IsCommunityPoolSpendType() bool {
159 return p.Type() == CommunityPoolSpend
160}
161
162// IsParameterChangeType reports whether the proposal changes governance parameters.
163//
164// Returns:
165// - bool: true when the proposal type is ParameterChange
166func (p *Proposal) IsParameterChangeType() bool {
167 return p.Type() == ParameterChange
168}
169
170// IsProposer reports whether addr matches the proposal's proposer address.
171//
172// Parameters:
173// - addr: address to compare with the proposal proposer
174//
175// Returns:
176// - bool: true when addr is the proposal proposer
177func (p *Proposal) IsProposer(addr address) bool {
178 return p.proposer == addr
179}
180
181// NewProposal creates a new proposal instance with the supplied identity,
182// lifecycle, metadata, and type-specific data.
183//
184// Parameters:
185// - proposalID: unique identifier assigned to the proposal
186// - status: initial schedule, action, and voting status
187// - metadata: proposal title and description metadata
188// - data: type-specific proposal data
189// - proposerAddress: address of the proposal creator
190// - configVersion: governance configuration version captured for the proposal
191// - snapshotTime: timestamp anchor for historical voting-weight lookup
192// - createdHeight: block height at which the proposal was created
193//
194// Returns:
195// - *Proposal: newly initialized proposal containing the supplied fields
196func NewProposal(
197 proposalID int64,
198 status *ProposalStatus,
199 metadata *ProposalMetadata,
200 data *ProposalData,
201 proposerAddress address,
202 configVersion int64,
203 snapshotTime int64,
204 createdHeight int64,
205) *Proposal {
206 return &Proposal{
207 id: proposalID,
208 proposer: proposerAddress,
209 status: status,
210 metadata: metadata,
211 data: data,
212 configVersion: configVersion,
213 snapshotTime: snapshotTime,
214 createdHeight: createdHeight,
215 }
216}
217
218// Clone returns a deep copy of the proposal, including its type-specific data
219// and nested execution messages.
220//
221// The returned proposal and all nested status, metadata, data, and message
222// values are independent copies; mutating the clone does not mutate realm state.
223//
224// Returns:
225// - *Proposal: independent proposal copy, or nil when the receiver is nil
226func (p *Proposal) Clone() *Proposal {
227 if p == nil {
228 return nil
229 }
230
231 return &Proposal{
232 id: p.id,
233 proposer: p.proposer,
234 configVersion: p.configVersion,
235 status: p.status.Clone(),
236 metadata: p.metadata.Clone(),
237 data: p.data.Clone(),
238 snapshotTime: p.snapshotTime,
239 createdHeight: p.createdHeight,
240 }
241}
242
243// NewProposalTree creates an empty B+ tree for proposals keyed by proposal ID.
244//
245// Returns:
246// - *bptree.BPTree: empty 16-way proposal tree
247func NewProposalTree() *bptree.BPTree {
248 return bptree.NewBPTreeN(16)
249}
250
251// NewUserProposalTree creates an empty B+ tree mapping users to proposal IDs.
252//
253// Returns:
254// - *bptree.BPTree: empty 16-way user-proposal index tree
255func NewUserProposalTree() *bptree.BPTree {
256 return bptree.NewBPTreeN(16)
257}
258
259// NewVotingInfoTree creates an empty B+ tree for per-user voting information.
260//
261// Returns:
262// - *bptree.BPTree: empty 16-way voting-information tree
263func NewVotingInfoTree() *bptree.BPTree {
264 return bptree.NewBPTreeN(16)
265}
266
267// NewProposalUserVotingInfoTree creates an empty B+ tree mapping proposal IDs
268// to their per-user voting-information trees.
269//
270// Returns:
271// - *bptree.BPTree: empty 16-way proposal voting-information index tree
272func NewProposalUserVotingInfoTree() *bptree.BPTree {
273 return bptree.NewBPTreeN(16)
274}