gpl_governance/processor/
process_set_realm_config.rs

1//! Program state processor
2
3use borsh::BorshSerialize;
4use gemachain_program::{
5    account_info::{next_account_info, AccountInfo},
6    entrypoint::ProgramResult,
7    pubkey::Pubkey,
8    rent::Rent,
9    sysvar::Sysvar,
10};
11use gpl_governance_tools::account::create_and_serialize_account_signed;
12
13use crate::{
14    error::GovernanceError,
15    state::{
16        enums::GovernanceAccountType,
17        realm::{assert_valid_realm_config_args, get_realm_data_for_authority, RealmConfigArgs},
18        realm_config::{
19            get_realm_config_address_seeds, get_realm_config_data_for_realm, RealmConfigAccount,
20        },
21    },
22};
23
24/// Processes SetRealmConfig instruction
25pub fn process_set_realm_config(
26    program_id: &Pubkey,
27    accounts: &[AccountInfo],
28    realm_config_args: RealmConfigArgs,
29) -> ProgramResult {
30    let account_info_iter = &mut accounts.iter();
31
32    let realm_info = next_account_info(account_info_iter)?; // 0
33    let realm_authority_info = next_account_info(account_info_iter)?; // 1
34
35    let mut realm_data =
36        get_realm_data_for_authority(program_id, realm_info, realm_authority_info.key)?;
37
38    if !realm_authority_info.is_signer {
39        return Err(GovernanceError::RealmAuthorityMustSign.into());
40    }
41
42    assert_valid_realm_config_args(&realm_config_args)?;
43
44    // Setup council
45    if realm_config_args.use_council_mint {
46        let council_token_mint_info = next_account_info(account_info_iter)?; // 2
47        let _council_token_holding_info = next_account_info(account_info_iter)?; // 3
48
49        // Council mint can only be at present set to none (removed) and changing it to other mint is not supported
50        // It might be implemented in future versions but it needs careful planning
51        // It can potentially open a can of warms like what happens with existing deposits or pending proposals
52        if let Some(council_token_mint) = realm_data.config.council_mint {
53            // Council mint can't be changed to different one
54            if council_token_mint != *council_token_mint_info.key {
55                return Err(GovernanceError::RealmCouncilMintChangeIsNotSupported.into());
56            }
57        } else {
58            // Council mint can't be restored (changed from None)
59            return Err(GovernanceError::RealmCouncilMintChangeIsNotSupported.into());
60        }
61    } else {
62        // Remove council mint from realm
63        // Note: In the current implementation this also makes it impossible to withdraw council tokens
64        realm_data.config.council_mint = None;
65    }
66
67    let system_info = next_account_info(account_info_iter)?; // 4
68    let realm_config_info = next_account_info(account_info_iter)?; // 5
69
70    // Setup community voter weight addin
71    if realm_config_args.use_community_voter_weight_addin {
72        let payer_info = next_account_info(account_info_iter)?; // 6
73        let community_voter_weight_addin_info = next_account_info(account_info_iter)?; // 7
74
75        if realm_config_info.data_is_empty() {
76            let realm_config_data = RealmConfigAccount {
77                account_type: GovernanceAccountType::RealmConfig,
78                realm: *realm_info.key,
79                community_voter_weight_addin: Some(*community_voter_weight_addin_info.key),
80                community_max_vote_weight_addin: None,
81                council_voter_weight_addin: None,
82                council_max_vote_weight_addin: None,
83                reserved: [0; 128],
84            };
85
86            let rent = Rent::get().unwrap();
87
88            create_and_serialize_account_signed::<RealmConfigAccount>(
89                payer_info,
90                realm_config_info,
91                &realm_config_data,
92                &get_realm_config_address_seeds(realm_info.key),
93                program_id,
94                system_info,
95                &rent,
96            )?;
97        } else {
98            let mut realm_config_data =
99                get_realm_config_data_for_realm(program_id, realm_config_info, realm_info.key)?;
100            realm_config_data.community_voter_weight_addin =
101                Some(*community_voter_weight_addin_info.key);
102            realm_config_data.serialize(&mut *realm_config_info.data.borrow_mut())?;
103        }
104    } else if realm_data.config.use_community_voter_weight_addin {
105        let mut realm_config_data =
106            get_realm_config_data_for_realm(program_id, realm_config_info, realm_info.key)?;
107        realm_config_data.community_voter_weight_addin = None;
108        realm_config_data.serialize(&mut *realm_config_info.data.borrow_mut())?;
109    }
110
111    realm_data.config.community_mint_max_vote_weight_source =
112        realm_config_args.community_mint_max_vote_weight_source;
113    realm_data.config.min_community_tokens_to_create_governance =
114        realm_config_args.min_community_tokens_to_create_governance;
115    realm_data.config.use_community_voter_weight_addin =
116        realm_config_args.use_community_voter_weight_addin;
117
118    realm_data.serialize(&mut *realm_info.data.borrow_mut())?;
119
120    Ok(())
121}