proposal.gno
4.94 Kb · 178 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 of the proposal.
19func (p *Proposal) ID() int64 {
20 return p.id
21}
22
23// Type returns the type of this proposal.
24func (p *Proposal) Type() ProposalType {
25 return p.data.ProposalType()
26}
27
28// Title returns the proposal title.
29func (p *Proposal) Title() string {
30 return p.metadata.Title()
31}
32
33// Description returns the proposal description.
34func (p *Proposal) Description() string {
35 return p.metadata.Description()
36}
37
38// Proposer returns the address of the proposal creator.
39func (p *Proposal) Proposer() address {
40 return p.proposer
41}
42
43// CreatedAt returns the creation timestamp of the proposal.
44func (p *Proposal) CreatedAt() int64 {
45 return p.status.schedule.createTime
46}
47
48// VotingYesWeight returns the total weight of "yes" votes.
49func (p *Proposal) VotingYesWeight() int64 {
50 return p.status.voteStatus.yea
51}
52
53// VotingNoWeight returns the total weight of "no" votes.
54func (p *Proposal) VotingNoWeight() int64 {
55 return p.status.voteStatus.nay
56}
57
58// VotingQuorumAmount returns minimum vote weight required for proposal to pass.
59func (p *Proposal) VotingQuorumAmount() int64 {
60 return p.status.voteStatus.quorumAmount
61}
62
63// VotingMaxWeight returns maximum possible voting weight for this proposal.
64func (p *Proposal) VotingMaxWeight() int64 {
65 return p.status.voteStatus.maxVotingWeight
66}
67
68// ConfigVersion returns the governance configuration version used for this proposal.
69func (p *Proposal) ConfigVersion() int64 {
70 return p.configVersion
71}
72
73// SnapshotTime returns the snapshot time for voting weight lookup.
74func (p *Proposal) SnapshotTime() int64 {
75 return p.snapshotTime
76}
77
78// Data returns the proposal data.
79func (p *Proposal) Data() *ProposalData {
80 return p.data
81}
82
83// Status returns the proposal status.
84func (p *Proposal) Status() *ProposalStatus {
85 return p.status
86}
87
88// Metadata returns the proposal metadata.
89func (p *Proposal) Metadata() *ProposalMetadata {
90 return p.metadata
91}
92
93// IsTextType checks if this is a text proposal.
94func (p *Proposal) IsTextType() bool {
95 return p.Type() == Text
96}
97
98// IsCommunityPoolSpendType checks if this is a community pool spend proposal.
99func (p *Proposal) IsCommunityPoolSpendType() bool {
100 return p.Type() == CommunityPoolSpend
101}
102
103// IsParameterChangeType checks if this is a parameter change proposal.
104func (p *Proposal) IsParameterChangeType() bool {
105 return p.Type() == ParameterChange
106}
107
108// IsProposer checks if the given address is the proposer of this proposal.
109func (p *Proposal) IsProposer(addr address) bool {
110 return p.proposer == addr
111}
112
113// NewProposal creates a new proposal instance with the provided parameters.
114// NewProposal is the main constructor for creating governance proposals.
115// - metadata: proposal title and description
116// - data: type-specific proposal data
117// - proposerAddress: address of the proposal creator
118// - configVersion: governance configuration version
119// - snapshotTime: timestamp for voting weight snapshot lookup
120// - createdHeight: creation block height
121//
122// Returns:
123// - *Proposal: newly created proposal instance
124func NewProposal(
125 proposalID int64,
126 status *ProposalStatus,
127 metadata *ProposalMetadata,
128 data *ProposalData,
129 proposerAddress address,
130 configVersion int64,
131 snapshotTime int64,
132 createdHeight int64,
133) *Proposal {
134 return &Proposal{
135 id: proposalID,
136 proposer: proposerAddress,
137 status: status,
138 metadata: metadata,
139 data: data,
140 configVersion: configVersion,
141 snapshotTime: snapshotTime,
142 createdHeight: createdHeight,
143 }
144}
145
146// Clone creates a deep copy of the Proposal.
147func (p *Proposal) Clone() *Proposal {
148 if p == nil {
149 return nil
150 }
151
152 return &Proposal{
153 id: p.id,
154 proposer: p.proposer,
155 configVersion: p.configVersion,
156 status: p.status.Clone(),
157 metadata: p.metadata.Clone(),
158 data: p.data.Clone(),
159 snapshotTime: p.snapshotTime,
160 createdHeight: p.createdHeight,
161 }
162}
163
164func NewProposalTree() *bptree.BPTree {
165 return bptree.NewBPTreeN(16)
166}
167
168func NewUserProposalTree() *bptree.BPTree {
169 return bptree.NewBPTreeN(16)
170}
171
172func NewVotingInfoTree() *bptree.BPTree {
173 return bptree.NewBPTreeN(16)
174}
175
176func NewProposalUserVotingInfoTree() *bptree.BPTree {
177 return bptree.NewBPTreeN(16)
178}