Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 2c50e98

Browse files
authored
Governance: Active proposal count (#131)
* feat: Add active_proposal_count to Governance * feat: Reallocate GovernanceV1 to GovernanceV2 * chore: test_create_proposal_and_migrate_v1_governance_to_v2 * chore: Cleanup code * chore: Update comments * chore: Use assert_is_valid_realm instead of deserializing the account * chore: Update comments * chore: Update comments * chore: Check for empty account first * chore: Update comments * fix: Assert new account size is greater than the existing one
1 parent 720a355 commit 2c50e98

30 files changed

+548
-92
lines changed

governance/program/src/instruction.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ pub enum GovernanceInstruction {
166166
///
167167
/// 0. `[]` Realm account the created Proposal belongs to
168168
/// 1. `[writable]` Proposal account. PDA seeds ['governance',governance, governing_token_mint, proposal_seed]
169-
/// 2. `[]` Governance account
169+
/// 2. `[writable]` Governance account
170170
/// 3. `[writable]` TokenOwnerRecord account of the Proposal owner
171171
/// 4. `[]` Governing Token Mint the Proposal is created for
172172
/// 5. `[signer]` Governance Authority (Token Owner or Governance Delegate)
@@ -270,7 +270,7 @@ pub enum GovernanceInstruction {
270270
/// Cancels Proposal by changing its state to Canceled
271271
///
272272
/// 0. `[]` Realm account
273-
/// 1. `[]` Governance account
273+
/// 1. `[writable]` Governance account
274274
/// 2. `[writable]` Proposal account
275275
/// 3. `[writable]` TokenOwnerRecord account of the Proposal owner
276276
/// 4. `[signer]` Governance Authority (Token Owner or Governance Delegate)
@@ -296,7 +296,7 @@ pub enum GovernanceInstruction {
296296
/// If you tip the consensus then the transactions can begin to be run after their hold up time
297297
///
298298
/// 0. `[]` Realm account
299-
/// 1. `[]` Governance account
299+
/// 1. `[writable]` Governance account
300300
/// 2. `[writable]` Proposal account
301301
/// 3. `[writable]` TokenOwnerRecord of the Proposal owner
302302
/// 4. `[writable]` TokenOwnerRecord of the voter. PDA seeds: ['governance',realm, vote_governing_token_mint, governing_token_owner]
@@ -321,7 +321,7 @@ pub enum GovernanceInstruction {
321321
/// Finalizes vote in case the Vote was not automatically tipped within max_voting_time period
322322
///
323323
/// 0. `[]` Realm account
324-
/// 1. `[]` Governance account
324+
/// 1. `[writable]` Governance account
325325
/// 2. `[writable]` Proposal account
326326
/// 3. `[writable]` TokenOwnerRecord of the Proposal owner
327327
/// 4. `[]` Governing Token Mint
@@ -909,7 +909,7 @@ pub fn create_proposal(
909909
let mut accounts = vec![
910910
AccountMeta::new_readonly(*realm, false),
911911
AccountMeta::new(proposal_address, false),
912-
AccountMeta::new_readonly(*governance, false),
912+
AccountMeta::new(*governance, false),
913913
AccountMeta::new(*proposal_owner_record, false),
914914
AccountMeta::new_readonly(*governing_token_mint, false),
915915
AccountMeta::new_readonly(*governance_authority, true),
@@ -1056,7 +1056,7 @@ pub fn cast_vote(
10561056

10571057
let mut accounts = vec![
10581058
AccountMeta::new_readonly(*realm, false),
1059-
AccountMeta::new_readonly(*governance, false),
1059+
AccountMeta::new(*governance, false),
10601060
AccountMeta::new(*proposal, false),
10611061
AccountMeta::new(*proposal_owner_record, false),
10621062
AccountMeta::new(*voter_token_owner_record, false),
@@ -1097,7 +1097,7 @@ pub fn finalize_vote(
10971097
) -> Instruction {
10981098
let mut accounts = vec![
10991099
AccountMeta::new_readonly(*realm, false),
1100-
AccountMeta::new_readonly(*governance, false),
1100+
AccountMeta::new(*governance, false),
11011101
AccountMeta::new(*proposal, false),
11021102
AccountMeta::new(*proposal_owner_record, false),
11031103
AccountMeta::new_readonly(*governing_token_mint, false),
@@ -1170,7 +1170,7 @@ pub fn cancel_proposal(
11701170
) -> Instruction {
11711171
let accounts = vec![
11721172
AccountMeta::new_readonly(*realm, false),
1173-
AccountMeta::new_readonly(*governance, false),
1173+
AccountMeta::new(*governance, false),
11741174
AccountMeta::new(*proposal, false),
11751175
AccountMeta::new(*proposal_owner_record, false),
11761176
AccountMeta::new_readonly(*governance_authority, true),

governance/program/src/processor/process_cancel_proposal.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use solana_program::{
1010

1111
use crate::state::{
1212
enums::ProposalState, governance::get_governance_data_for_realm,
13-
proposal::get_proposal_data_for_governance, realm::get_realm_data,
13+
proposal::get_proposal_data_for_governance, realm::assert_is_valid_realm,
1414
token_owner_record::get_token_owner_record_data_for_proposal_owner,
1515
};
1616

@@ -26,11 +26,9 @@ pub fn process_cancel_proposal(program_id: &Pubkey, accounts: &[AccountInfo]) ->
2626

2727
let clock = Clock::get()?;
2828

29-
// Realm is deserialized to validate the account
30-
// Note: It'll be used in the future versions to track active proposals
31-
let _realm_data = get_realm_data(program_id, realm_info)?;
29+
assert_is_valid_realm(program_id, realm_info)?;
3230

33-
let governance_data =
31+
let mut governance_data =
3432
get_governance_data_for_realm(program_id, governance_info, realm_info.key)?;
3533

3634
let mut proposal_data =
@@ -54,5 +52,9 @@ pub fn process_cancel_proposal(program_id: &Pubkey, accounts: &[AccountInfo]) ->
5452

5553
proposal_data.serialize(&mut *proposal_info.data.borrow_mut())?;
5654

55+
// Update Governance active_proposal_count
56+
governance_data.active_proposal_count = governance_data.active_proposal_count.saturating_sub(1);
57+
governance_data.serialize(&mut *governance_info.data.borrow_mut())?;
58+
5759
Ok(())
5860
}

governance/program/src/processor/process_cast_vote.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub fn process_cast_vote(
6363
vote_governing_token_mint_info.key,
6464
)?;
6565

66-
let governance_data =
66+
let mut governance_data =
6767
get_governance_data_for_realm(program_id, governance_info, realm_info.key)?;
6868

6969
let vote_kind = get_vote_kind(&vote);
@@ -181,6 +181,11 @@ pub fn process_cast_vote(
181181
proposal_owner_record_data
182182
.serialize(&mut *proposal_owner_record_info.data.borrow_mut())?;
183183
};
184+
185+
// If the proposal is tipped decrease Governance active_proposal_count
186+
governance_data.active_proposal_count =
187+
governance_data.active_proposal_count.saturating_sub(1);
188+
governance_data.serialize(&mut *governance_info.data.borrow_mut())?;
184189
}
185190

186191
let governing_token_owner = voter_token_owner_record_data.governing_token_owner;

governance/program/src/processor/process_create_governance.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
//! Program state processor
22
3-
use crate::state::{
4-
enums::GovernanceAccountType,
5-
governance::{
6-
assert_valid_create_governance_args, get_governance_address_seeds, GovernanceConfig,
7-
GovernanceV2,
3+
use crate::{
4+
state::{
5+
enums::GovernanceAccountType,
6+
governance::{
7+
assert_valid_create_governance_args, get_governance_address_seeds, GovernanceConfig,
8+
GovernanceV2,
9+
},
10+
realm::get_realm_data,
811
},
9-
realm::get_realm_data,
12+
tools::structs::Reserved120,
1013
};
1114
use solana_program::{
1215
account_info::{next_account_info, AccountInfo},
@@ -57,7 +60,8 @@ pub fn process_create_governance(
5760
governed_account: *governed_account_info.key,
5861
config,
5962
reserved1: 0,
60-
reserved_v2: [0; 128],
63+
reserved_v2: Reserved120::default(),
64+
active_proposal_count: 0,
6165
};
6266

6367
create_and_serialize_account_signed::<GovernanceV2>(

governance/program/src/processor/process_create_mint_governance.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ use crate::{
99
},
1010
realm::get_realm_data,
1111
},
12-
tools::spl_token::{
13-
assert_spl_token_mint_authority_is_signer, set_spl_token_account_authority,
12+
tools::{
13+
spl_token::{assert_spl_token_mint_authority_is_signer, set_spl_token_account_authority},
14+
structs::Reserved120,
1415
},
1516
};
1617
use solana_program::{
@@ -69,7 +70,8 @@ pub fn process_create_mint_governance(
6970
governed_account: *governed_mint_info.key,
7071
config,
7172
reserved1: 0,
72-
reserved_v2: [0; 128],
73+
reserved_v2: Reserved120::default(),
74+
active_proposal_count: 0,
7375
};
7476

7577
create_and_serialize_account_signed::<GovernanceV2>(

governance/program/src/processor/process_create_program_governance.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,11 @@ use crate::{
1010
},
1111
realm::get_realm_data,
1212
},
13-
tools::bpf_loader_upgradeable::{
14-
assert_program_upgrade_authority_is_signer, set_program_upgrade_authority,
13+
tools::{
14+
bpf_loader_upgradeable::{
15+
assert_program_upgrade_authority_is_signer, set_program_upgrade_authority,
16+
},
17+
structs::Reserved120,
1518
},
1619
};
1720
use solana_program::{
@@ -69,7 +72,8 @@ pub fn process_create_program_governance(
6972
governed_account: *governed_program_info.key,
7073
config,
7174
reserved1: 0,
72-
reserved_v2: [0; 128],
75+
reserved_v2: Reserved120::default(),
76+
active_proposal_count: 0,
7377
};
7478

7579
create_and_serialize_account_signed::<GovernanceV2>(

governance/program/src/processor/process_create_proposal.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub fn process_create_proposal(
6565
governing_token_mint_info.key,
6666
)?;
6767

68-
let governance_data =
68+
let mut governance_data =
6969
get_governance_data_for_realm(program_id, governance_info, realm_info.key)?;
7070

7171
governance_data.assert_governing_token_mint_can_vote(
@@ -178,5 +178,13 @@ pub fn process_create_proposal(
178178
&rent,
179179
)?;
180180

181+
governance_data.active_proposal_count = governance_data
182+
.active_proposal_count
183+
.checked_add(1)
184+
.unwrap();
185+
186+
// Serialize the governance account update to GovernanceV2 if needed
187+
governance_data.serialize_as_governance_v2(governance_info, payer_info, system_info, &rent)?;
188+
181189
Ok(())
182190
}

governance/program/src/processor/process_create_realm.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ use crate::{
1919
},
2020
realm_config::{
2121
get_realm_config_address_seeds, resolve_governing_token_config, RealmConfigAccount,
22-
Reserved110,
2322
},
2423
},
25-
tools::spl_token::create_spl_token_account_signed,
24+
tools::{spl_token::create_spl_token_account_signed, structs::Reserved110},
2625
};
2726

2827
/// Processes CreateRealm instruction

governance/program/src/processor/process_create_token_governance.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ use crate::{
99
},
1010
realm::get_realm_data,
1111
},
12-
tools::spl_token::{assert_spl_token_owner_is_signer, set_spl_token_account_authority},
12+
tools::{
13+
spl_token::{assert_spl_token_owner_is_signer, set_spl_token_account_authority},
14+
structs::Reserved120,
15+
},
1316
};
1417
use solana_program::{
1518
account_info::{next_account_info, AccountInfo},
@@ -67,7 +70,8 @@ pub fn process_create_token_governance(
6770
governed_account: *governed_token_info.key,
6871
config,
6972
reserved1: 0,
70-
reserved_v2: [0; 128],
73+
reserved_v2: Reserved120::default(),
74+
active_proposal_count: 0,
7175
};
7276

7377
create_and_serialize_account_signed::<GovernanceV2>(

governance/program/src/processor/process_finalize_vote.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ pub fn process_finalize_vote(program_id: &Pubkey, accounts: &[AccountInfo]) -> P
3333
realm_info,
3434
governing_token_mint_info.key,
3535
)?;
36-
let governance_data =
36+
let mut governance_data =
3737
get_governance_data_for_realm(program_id, governance_info, realm_info.key)?;
3838

3939
let mut proposal_data = get_proposal_data_for_governance_and_governing_mint(
@@ -80,5 +80,9 @@ pub fn process_finalize_vote(program_id: &Pubkey, accounts: &[AccountInfo]) -> P
8080

8181
proposal_data.serialize(&mut *proposal_info.data.borrow_mut())?;
8282

83+
// Update Governance active_proposal_count
84+
governance_data.active_proposal_count = governance_data.active_proposal_count.saturating_sub(1);
85+
governance_data.serialize(&mut *governance_info.data.borrow_mut())?;
86+
8387
Ok(())
8488
}

0 commit comments

Comments
 (0)