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

Commit 49c5cd7

Browse files
authored
Governance: Remove Realm voting proposal count (#128)
* feat: Remove Realm.voting_proposal_count * chore: Update comments * chore: Add tests and explicit assertions for non existing accounts
1 parent 79b59a3 commit 49c5cd7

23 files changed

+162
-129
lines changed

governance/program/src/instruction.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ pub enum GovernanceInstruction {
269269

270270
/// Cancels Proposal by changing its state to Canceled
271271
///
272-
/// 0. `[writable]` Realm account
272+
/// 0. `[]` Realm account
273273
/// 1. `[]` Governance account
274274
/// 2. `[writable]` Proposal account
275275
/// 3. `[writable]` TokenOwnerRecord account of the Proposal owner
@@ -282,7 +282,7 @@ pub enum GovernanceInstruction {
282282
/// it's entirely at the discretion of the Proposal owner
283283
/// If Proposal owner doesn't designate any signatories then can sign off the Proposal themself
284284
///
285-
/// 0. `[writable]` Realm account
285+
/// 0. `[]` Realm account
286286
/// 1. `[]` Governance account
287287
/// 2. `[writable]` Proposal account
288288
/// 3. `[signer]` Signatory account signing off the Proposal
@@ -295,7 +295,7 @@ pub enum GovernanceInstruction {
295295
/// By doing so you indicate you approve or disapprove of running the Proposal set of transactions
296296
/// If you tip the consensus then the transactions can begin to be run after their hold up time
297297
///
298-
/// 0. `[writable]` Realm account
298+
/// 0. `[]` Realm account
299299
/// 1. `[]` Governance account
300300
/// 2. `[writable]` Proposal account
301301
/// 3. `[writable]` TokenOwnerRecord of the Proposal owner
@@ -320,7 +320,7 @@ pub enum GovernanceInstruction {
320320

321321
/// Finalizes vote in case the Vote was not automatically tipped within max_voting_time period
322322
///
323-
/// 0. `[writable]` Realm account
323+
/// 0. `[]` Realm account
324324
/// 1. `[]` Governance account
325325
/// 2. `[writable]` Proposal account
326326
/// 3. `[writable]` TokenOwnerRecord of the Proposal owner
@@ -1010,7 +1010,7 @@ pub fn sign_off_proposal(
10101010
proposal_owner_record: Option<&Pubkey>,
10111011
) -> Instruction {
10121012
let mut accounts = vec![
1013-
AccountMeta::new(*realm, false),
1013+
AccountMeta::new_readonly(*realm, false),
10141014
AccountMeta::new_readonly(*governance, false),
10151015
AccountMeta::new(*proposal, false),
10161016
AccountMeta::new_readonly(*signatory, true),
@@ -1055,7 +1055,7 @@ pub fn cast_vote(
10551055
get_vote_record_address(program_id, proposal, voter_token_owner_record);
10561056

10571057
let mut accounts = vec![
1058-
AccountMeta::new(*realm, false),
1058+
AccountMeta::new_readonly(*realm, false),
10591059
AccountMeta::new_readonly(*governance, false),
10601060
AccountMeta::new(*proposal, false),
10611061
AccountMeta::new(*proposal_owner_record, false),
@@ -1096,7 +1096,7 @@ pub fn finalize_vote(
10961096
max_voter_weight_record: Option<Pubkey>,
10971097
) -> Instruction {
10981098
let mut accounts = vec![
1099-
AccountMeta::new(*realm, false),
1099+
AccountMeta::new_readonly(*realm, false),
11001100
AccountMeta::new_readonly(*governance, false),
11011101
AccountMeta::new(*proposal, false),
11021102
AccountMeta::new(*proposal_owner_record, false),
@@ -1169,7 +1169,7 @@ pub fn cancel_proposal(
11691169
governance_authority: &Pubkey,
11701170
) -> Instruction {
11711171
let accounts = vec![
1172-
AccountMeta::new(*realm, false),
1172+
AccountMeta::new_readonly(*realm, false),
11731173
AccountMeta::new_readonly(*governance, false),
11741174
AccountMeta::new(*proposal, false),
11751175
AccountMeta::new(*proposal_owner_record, false),

governance/program/src/processor/process_cancel_proposal.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ pub fn process_cancel_proposal(program_id: &Pubkey, accounts: &[AccountInfo]) ->
2626

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

29-
let mut realm_data = get_realm_data(program_id, realm_info)?;
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)?;
3032

3133
let governance_data =
3234
get_governance_data_for_realm(program_id, governance_info, realm_info.key)?;
@@ -47,12 +49,6 @@ pub fn process_cancel_proposal(program_id: &Pubkey, accounts: &[AccountInfo]) ->
4749
proposal_owner_record_data.decrease_outstanding_proposal_count();
4850
proposal_owner_record_data.serialize(&mut *proposal_owner_record_info.data.borrow_mut())?;
4951

50-
if proposal_data.state == ProposalState::Voting {
51-
// Update Realm voting_proposal_count
52-
realm_data.voting_proposal_count = realm_data.voting_proposal_count.saturating_sub(1);
53-
realm_data.serialize(&mut *realm_info.data.borrow_mut())?;
54-
}
55-
5652
proposal_data.state = ProposalState::Cancelled;
5753
proposal_data.closed_at = Some(clock.unix_timestamp);
5854

governance/program/src/processor/process_cast_vote.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ pub fn process_cast_vote(
5757
return Err(GovernanceError::VoteAlreadyExists.into());
5858
}
5959

60-
let mut realm_data = get_realm_data_for_governing_token_mint(
60+
let realm_data = get_realm_data_for_governing_token_mint(
6161
program_id,
6262
realm_info,
6363
vote_governing_token_mint_info.key,
@@ -186,10 +186,6 @@ pub fn process_cast_vote(
186186
proposal_owner_record_data
187187
.serialize(&mut *proposal_owner_record_info.data.borrow_mut())?;
188188
};
189-
190-
// Update Realm voting_proposal_count
191-
realm_data.voting_proposal_count = realm_data.voting_proposal_count.saturating_sub(1);
192-
realm_data.serialize(&mut *realm_info.data.borrow_mut())?;
193189
}
194190

195191
let governing_token_owner = voter_token_owner_record_data.governing_token_owner;

governance/program/src/processor/process_create_realm.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ pub fn process_create_realm(
139139
legacy1: 0,
140140
legacy2: 0,
141141
},
142-
voting_proposal_count: 0,
142+
legacy1: 0,
143143
reserved_v2: [0; 128],
144144
};
145145

governance/program/src/processor/process_finalize_vote.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub fn process_finalize_vote(program_id: &Pubkey, accounts: &[AccountInfo]) -> P
2828

2929
let clock = Clock::get()?;
3030

31-
let mut realm_data = get_realm_data_for_governing_token_mint(
31+
let realm_data = get_realm_data_for_governing_token_mint(
3232
program_id,
3333
realm_info,
3434
governing_token_mint_info.key,
@@ -80,9 +80,5 @@ 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 Realm voting_proposal_count
84-
realm_data.voting_proposal_count = realm_data.voting_proposal_count.saturating_sub(1);
85-
realm_data.serialize(&mut *realm_info.data.borrow_mut())?;
86-
8783
Ok(())
8884
}

governance/program/src/processor/process_set_governance_config.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,9 @@ pub fn process_set_governance_config(
3030

3131
let mut governance_data = get_governance_data(program_id, governance_info)?;
3232

33-
// Until we have Veto implemented it's better to allow config change as the defense of last resort against governance attacks
3433
// Note: Config change leaves voting proposals in unpredictable state and it's DAOs responsibility
3534
// to ensure the changes are made when there are no proposals in voting state
3635
// For example changing approval quorum could accidentally make proposals to succeed which would otherwise be defeated
37-
// The check wouldn't have any effect when upgrading from V1 to V2 because it was not tracked in V1
38-
39-
// if governance_data.voting_proposal_count > 0 {
40-
// return Err(GovernanceError::GovernanceConfigChangeNotAllowed.into());
41-
// }
4236

4337
governance_data.config = config;
4438

governance/program/src/processor/process_set_realm_config.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,9 @@ pub fn process_set_realm_config(
3939
return Err(GovernanceError::RealmAuthorityMustSign.into());
4040
}
4141

42-
// Until we have Veto implemented it's better to allow config change as the defense of last resort against governance attacks
4342
// Note: Config change leaves voting proposals in unpredictable state and it's DAOs responsibility
4443
// to ensure the changes are made when there are no proposals in voting state
4544
// For example changing voter-weight or max-voter-weight addin could accidentally make proposals to succeed which would otherwise be defeated
46-
// The check wouldn't have any effect when upgrading from V1 to V2 because it was not tracked in V1
47-
48-
// if realm_data.voting_proposal_count > 0 {
49-
// return Err(GovernanceError::RealmConfigChangeNotAllowed.into());
50-
// }
5145

5246
assert_valid_realm_config_args(&realm_config_args)?;
5347

governance/program/src/processor/process_sign_off_proposal.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ pub fn process_sign_off_proposal(program_id: &Pubkey, accounts: &[AccountInfo])
2727

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

30-
let mut realm_data = get_realm_data(program_id, realm_info)?;
30+
// Realm is deserialized to validate the account
31+
let _realm_data = get_realm_data(program_id, realm_info)?;
3132

3233
// Governance account data is no longer used in the current version but we still have to load it to validate Realm -> Governance -> Proposal relationship
3334
// It could be replaced with PDA check but the account is going to be needed in future versions once we support mandatory signatories
@@ -89,8 +90,5 @@ pub fn process_sign_off_proposal(program_id: &Pubkey, accounts: &[AccountInfo])
8990

9091
proposal_data.serialize(&mut *proposal_info.data.borrow_mut())?;
9192

92-
realm_data.voting_proposal_count = realm_data.voting_proposal_count.checked_add(1).unwrap();
93-
realm_data.serialize(&mut *realm_info.data.borrow_mut())?;
94-
9593
Ok(())
9694
}

governance/program/src/state/enums.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub enum GovernanceAccountType {
6060
/// Top level aggregation for governances with Community Token (and optional Council Token)
6161
/// V2 adds the following fields:
6262
/// 1) use_community_voter_weight_addin and use_max_community_voter_weight_addin to RealmConfig
63-
/// 2) voting_proposal_count
63+
/// 2) voting_proposal_count / replaced with legacy1 in V3
6464
/// 3) extra reserved space reserved_v2
6565
RealmV2,
6666

governance/program/src/state/governance.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ use crate::{
1212
};
1313
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
1414
use solana_program::{
15-
account_info::AccountInfo, borsh::try_from_slice_unchecked, program_error::ProgramError,
16-
program_pack::IsInitialized, pubkey::Pubkey,
15+
account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized,
16+
pubkey::Pubkey,
1717
};
1818
use spl_governance_tools::{
19-
account::{assert_is_valid_account_of_types, get_account_data, AccountMaxSize},
19+
account::{
20+
assert_is_valid_account_of_types, get_account_data, get_account_type, AccountMaxSize,
21+
},
2022
error::GovernanceToolsError,
2123
};
2224

@@ -267,12 +269,7 @@ pub fn get_governance_data(
267269
program_id: &Pubkey,
268270
governance_info: &AccountInfo,
269271
) -> Result<GovernanceV2, ProgramError> {
270-
if governance_info.data_is_empty() {
271-
return Err(GovernanceToolsError::AccountDoesNotExist.into());
272-
}
273-
274-
let account_type: GovernanceAccountType =
275-
try_from_slice_unchecked(&governance_info.data.borrow())?;
272+
let account_type: GovernanceAccountType = get_account_type(program_id, governance_info)?;
276273

277274
// If the account is V1 version then translate to V2
278275
let mut governance_data = if is_governance_v1_account_type(&account_type) {

0 commit comments

Comments
 (0)