Governance: Realm config (#2166)
* feat: create RealmConfig and move council to it * feat: add realm custodian to config * feat: add community_mint_max_vote_weight_source tp realm config * chore: fix data types
This commit is contained in:
parent
60aeb7c56c
commit
a74c5b998b
|
@ -3758,7 +3758,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spl-governance"
|
name = "spl-governance"
|
||||||
version = "1.0.4"
|
version = "1.0.6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "spl-governance"
|
name = "spl-governance"
|
||||||
version = "1.0.4"
|
version = "1.0.6"
|
||||||
description = "Solana Program Library Governance Program"
|
description = "Solana Program Library Governance Program"
|
||||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||||
repository = "https://github.com/solana-labs/solana-program-library"
|
repository = "https://github.com/solana-labs/solana-program-library"
|
||||||
|
|
|
@ -244,16 +244,17 @@ pub enum GovernanceInstruction {
|
||||||
/// By doing so you indicate you approve or disapprove of running the Proposal set of instructions
|
/// By doing so you indicate you approve or disapprove of running the Proposal set of instructions
|
||||||
/// If you tip the consensus then the instructions can begin to be run after their hold up time
|
/// If you tip the consensus then the instructions can begin to be run after their hold up time
|
||||||
///
|
///
|
||||||
/// 0. `[]` Governance account
|
/// 0. `[]` Realm account
|
||||||
/// 1. `[writable]` Proposal account
|
/// 1. `[]` Governance account
|
||||||
/// 2. `[writable]` Token Owner Record account. PDA seeds: ['governance',realm, governing_token_mint, governing_token_owner]
|
/// 2. `[writable]` Proposal account
|
||||||
/// 3. `[signer]` Governance Authority (Token Owner or Governance Delegate)
|
/// 3. `[writable]` Token Owner Record account. PDA seeds: ['governance',realm, governing_token_mint, governing_token_owner]
|
||||||
/// 4. `[writable]` Proposal VoteRecord account. PDA seeds: ['governance',proposal,governing_token_owner_record]
|
/// 4. `[signer]` Governance Authority (Token Owner or Governance Delegate)
|
||||||
/// 5. `[]` Governing Token Mint
|
/// 5. `[writable]` Proposal VoteRecord account. PDA seeds: ['governance',proposal,governing_token_owner_record]
|
||||||
/// 6. `[signer]` Payer
|
/// 6. `[]` Governing Token Mint
|
||||||
/// 7. `[]` System program
|
/// 7. `[signer]` Payer
|
||||||
/// 8. `[]` Rent sysvar
|
/// 8. `[]` System program
|
||||||
/// 9. `[]` Clock sysvar
|
/// 9. `[]` Rent sysvar
|
||||||
|
/// 10. `[]` Clock sysvar
|
||||||
CastVote {
|
CastVote {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
/// Yes/No vote
|
/// Yes/No vote
|
||||||
|
@ -262,10 +263,11 @@ pub enum GovernanceInstruction {
|
||||||
|
|
||||||
/// Finalizes vote in case the Vote was not automatically tipped within max_voting_time period
|
/// Finalizes vote in case the Vote was not automatically tipped within max_voting_time period
|
||||||
///
|
///
|
||||||
/// 0. `[]` Governance account
|
/// 0. `[]` Realm account
|
||||||
/// 1. `[writable]` Proposal account
|
/// 1. `[]` Governance account
|
||||||
/// 2. `[]` Governing Token Mint
|
/// 2. `[writable]` Proposal account
|
||||||
/// 3. `[]` Clock sysvar
|
/// 3. `[]` Governing Token Mint
|
||||||
|
/// 4. `[]` Clock sysvar
|
||||||
FinalizeVote {},
|
FinalizeVote {},
|
||||||
|
|
||||||
/// Relinquish Vote removes voter weight from a Proposal and removes it from voter's active votes
|
/// Relinquish Vote removes voter weight from a Proposal and removes it from voter's active votes
|
||||||
|
@ -820,6 +822,7 @@ pub fn sign_off_proposal(
|
||||||
pub fn cast_vote(
|
pub fn cast_vote(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
// Accounts
|
// Accounts
|
||||||
|
realm: &Pubkey,
|
||||||
governance: &Pubkey,
|
governance: &Pubkey,
|
||||||
proposal: &Pubkey,
|
proposal: &Pubkey,
|
||||||
token_owner_record: &Pubkey,
|
token_owner_record: &Pubkey,
|
||||||
|
@ -832,6 +835,7 @@ pub fn cast_vote(
|
||||||
let vote_record_address = get_vote_record_address(program_id, proposal, token_owner_record);
|
let vote_record_address = get_vote_record_address(program_id, proposal, token_owner_record);
|
||||||
|
|
||||||
let accounts = vec![
|
let accounts = vec![
|
||||||
|
AccountMeta::new_readonly(*realm, false),
|
||||||
AccountMeta::new_readonly(*governance, false),
|
AccountMeta::new_readonly(*governance, false),
|
||||||
AccountMeta::new(*proposal, false),
|
AccountMeta::new(*proposal, false),
|
||||||
AccountMeta::new(*token_owner_record, false),
|
AccountMeta::new(*token_owner_record, false),
|
||||||
|
@ -857,11 +861,13 @@ pub fn cast_vote(
|
||||||
pub fn finalize_vote(
|
pub fn finalize_vote(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
// Accounts
|
// Accounts
|
||||||
|
realm: &Pubkey,
|
||||||
governance: &Pubkey,
|
governance: &Pubkey,
|
||||||
proposal: &Pubkey,
|
proposal: &Pubkey,
|
||||||
governing_token_mint: &Pubkey,
|
governing_token_mint: &Pubkey,
|
||||||
) -> Instruction {
|
) -> Instruction {
|
||||||
let accounts = vec![
|
let accounts = vec![
|
||||||
|
AccountMeta::new_readonly(*realm, false),
|
||||||
AccountMeta::new_readonly(*governance, false),
|
AccountMeta::new_readonly(*governance, false),
|
||||||
AccountMeta::new(*proposal, false),
|
AccountMeta::new(*proposal, false),
|
||||||
AccountMeta::new_readonly(*governing_token_mint, false),
|
AccountMeta::new_readonly(*governing_token_mint, false),
|
||||||
|
|
|
@ -32,21 +32,22 @@ pub fn process_cast_vote(
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
|
|
||||||
let governance_info = next_account_info(account_info_iter)?; // 0
|
let _realm_info = next_account_info(account_info_iter)?; // 0
|
||||||
let proposal_info = next_account_info(account_info_iter)?; // 1
|
let governance_info = next_account_info(account_info_iter)?; // 1
|
||||||
let token_owner_record_info = next_account_info(account_info_iter)?; // 2
|
let proposal_info = next_account_info(account_info_iter)?; // 2
|
||||||
let governance_authority_info = next_account_info(account_info_iter)?; // 3
|
let token_owner_record_info = next_account_info(account_info_iter)?; // 3
|
||||||
|
let governance_authority_info = next_account_info(account_info_iter)?; // 4
|
||||||
|
|
||||||
let vote_record_info = next_account_info(account_info_iter)?; // 4
|
let vote_record_info = next_account_info(account_info_iter)?; // 5
|
||||||
let governing_token_mint_info = next_account_info(account_info_iter)?; // 5
|
let governing_token_mint_info = next_account_info(account_info_iter)?; // 6
|
||||||
|
|
||||||
let payer_info = next_account_info(account_info_iter)?; // 6
|
let payer_info = next_account_info(account_info_iter)?; // 7
|
||||||
let system_info = next_account_info(account_info_iter)?; // 7
|
let system_info = next_account_info(account_info_iter)?; // 8
|
||||||
|
|
||||||
let rent_sysvar_info = next_account_info(account_info_iter)?; // 8
|
let rent_sysvar_info = next_account_info(account_info_iter)?; // 9
|
||||||
let rent = &Rent::from_account_info(rent_sysvar_info)?;
|
let rent = &Rent::from_account_info(rent_sysvar_info)?;
|
||||||
|
|
||||||
let clock_info = next_account_info(account_info_iter)?; // 9
|
let clock_info = next_account_info(account_info_iter)?; // 10
|
||||||
let clock = Clock::from_account_info(clock_info)?;
|
let clock = Clock::from_account_info(clock_info)?;
|
||||||
|
|
||||||
if !vote_record_info.data_is_empty() {
|
if !vote_record_info.data_is_empty() {
|
||||||
|
|
|
@ -11,8 +11,10 @@ use solana_program::{
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
state::{
|
state::{
|
||||||
enums::GovernanceAccountType,
|
enums::{GovernanceAccountType, MintMaxVoteWeightSource},
|
||||||
realm::{get_governing_token_holding_address_seeds, get_realm_address_seeds, Realm},
|
realm::{
|
||||||
|
get_governing_token_holding_address_seeds, get_realm_address_seeds, Realm, RealmConfig,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
tools::{
|
tools::{
|
||||||
account::create_and_serialize_account_signed, spl_token::create_spl_token_account_signed,
|
account::create_and_serialize_account_signed, spl_token::create_spl_token_account_signed,
|
||||||
|
@ -82,10 +84,16 @@ pub fn process_create_realm(
|
||||||
let realm_data = Realm {
|
let realm_data = Realm {
|
||||||
account_type: GovernanceAccountType::Realm,
|
account_type: GovernanceAccountType::Realm,
|
||||||
community_mint: *governance_token_mint_info.key,
|
community_mint: *governance_token_mint_info.key,
|
||||||
council_mint: council_token_mint_address,
|
|
||||||
name: name.clone(),
|
name: name.clone(),
|
||||||
reserved: [0; 8],
|
reserved: [0; 8],
|
||||||
authority: Some(*realm_authority_info.key),
|
authority: Some(*realm_authority_info.key),
|
||||||
|
config: RealmConfig {
|
||||||
|
council_mint: council_token_mint_address,
|
||||||
|
reserved: [0; 8],
|
||||||
|
custodian: Some(*realm_authority_info.key),
|
||||||
|
community_mint_max_vote_weight_source: MintMaxVoteWeightSource::Percentage(100),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
create_and_serialize_account_signed::<Realm>(
|
create_and_serialize_account_signed::<Realm>(
|
||||||
|
|
|
@ -22,12 +22,13 @@ use borsh::BorshSerialize;
|
||||||
pub fn process_finalize_vote(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
pub fn process_finalize_vote(program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
|
||||||
let account_info_iter = &mut accounts.iter();
|
let account_info_iter = &mut accounts.iter();
|
||||||
|
|
||||||
let governance_info = next_account_info(account_info_iter)?; // 0
|
let _realm_info = next_account_info(account_info_iter)?; // 0
|
||||||
let proposal_info = next_account_info(account_info_iter)?; // 1
|
let governance_info = next_account_info(account_info_iter)?; // 1
|
||||||
|
let proposal_info = next_account_info(account_info_iter)?; // 2
|
||||||
|
|
||||||
let governing_token_mint_info = next_account_info(account_info_iter)?; // 2
|
let governing_token_mint_info = next_account_info(account_info_iter)?; // 3
|
||||||
|
|
||||||
let clock_info = next_account_info(account_info_iter)?; // 3
|
let clock_info = next_account_info(account_info_iter)?; // 4
|
||||||
let clock = Clock::from_account_info(clock_info)?;
|
let clock = Clock::from_account_info(clock_info)?;
|
||||||
|
|
||||||
let governance_data = get_governance_data(program_id, governance_info)?;
|
let governance_data = get_governance_data(program_id, governance_info)?;
|
||||||
|
|
|
@ -159,3 +159,17 @@ pub enum InstructionExecutionFlags {
|
||||||
/// The implementation requires another account type to group instructions within a transaction
|
/// The implementation requires another account type to group instructions within a transaction
|
||||||
UseTransaction,
|
UseTransaction,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The source of max vote weight used for voting
|
||||||
|
/// Values below 100% mint supply can be used when the governing token is fully minted but not distributed yet
|
||||||
|
/// Note: This field is not used yet. It's reserved for future versions
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
|
||||||
|
pub enum MintMaxVoteWeightSource {
|
||||||
|
/// Percentage of the governing mint supply is used as max vote weight
|
||||||
|
/// The default is 100% to use all available mint supply for voting
|
||||||
|
Percentage(u8),
|
||||||
|
|
||||||
|
/// Absolute value, irrelevant of the actual mint supply, is used as max vote weight
|
||||||
|
Absolute(u64),
|
||||||
|
}
|
||||||
|
|
|
@ -8,11 +8,32 @@ use solana_program::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
|
state::enums::{GovernanceAccountType, MintMaxVoteWeightSource},
|
||||||
tools::account::{assert_is_valid_account, get_account_data, AccountMaxSize},
|
tools::account::{assert_is_valid_account, get_account_data, AccountMaxSize},
|
||||||
PROGRAM_AUTHORITY_SEED,
|
PROGRAM_AUTHORITY_SEED,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::state::enums::GovernanceAccountType;
|
/// Realm Config defining Realm parameters.
|
||||||
|
#[repr(C)]
|
||||||
|
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
|
||||||
|
pub struct RealmConfig {
|
||||||
|
/// Optional council mint
|
||||||
|
pub council_mint: Option<Pubkey>,
|
||||||
|
|
||||||
|
/// The source used for community mint max vote weight source
|
||||||
|
/// Note: This field is not used yet. It's reserved for future versions
|
||||||
|
pub community_mint_max_vote_weight_source: MintMaxVoteWeightSource,
|
||||||
|
|
||||||
|
/// An authority tasked with none critical and maintenance Realm operations
|
||||||
|
/// For example custodian authority is required to add governances to the Realm
|
||||||
|
/// There is no security risk with adding governances to the Realm but it should not be open for everybody
|
||||||
|
/// to prevent unrelated entries and noise
|
||||||
|
/// Note: This field is not used yet. It's reserved for future versions
|
||||||
|
pub custodian: Option<Pubkey>,
|
||||||
|
|
||||||
|
/// Reserved space for future versions
|
||||||
|
pub reserved: [u8; 8],
|
||||||
|
}
|
||||||
|
|
||||||
/// Governance Realm Account
|
/// Governance Realm Account
|
||||||
/// Account PDA seeds" ['governance', name]
|
/// Account PDA seeds" ['governance', name]
|
||||||
|
@ -25,13 +46,13 @@ pub struct Realm {
|
||||||
/// Community mint
|
/// Community mint
|
||||||
pub community_mint: Pubkey,
|
pub community_mint: Pubkey,
|
||||||
|
|
||||||
|
/// Configuration of the Realm
|
||||||
|
pub config: RealmConfig,
|
||||||
|
|
||||||
/// Reserved space for future versions
|
/// Reserved space for future versions
|
||||||
pub reserved: [u8; 8],
|
pub reserved: [u8; 8],
|
||||||
|
|
||||||
/// Council mint
|
/// Realm authority. The authority must sign transactions which update the realm config
|
||||||
pub council_mint: Option<Pubkey>,
|
|
||||||
|
|
||||||
/// Realm authority. The authority must sign transactions which update the realm (ex. adding governance, setting council)
|
|
||||||
/// The authority can be transferer to Realm Governance and hence make the Realm self governed through proposals
|
/// The authority can be transferer to Realm Governance and hence make the Realm self governed through proposals
|
||||||
/// Note: This field is not used yet. It's reserved for future versions
|
/// Note: This field is not used yet. It's reserved for future versions
|
||||||
pub authority: Option<Pubkey>,
|
pub authority: Option<Pubkey>,
|
||||||
|
@ -42,7 +63,7 @@ pub struct Realm {
|
||||||
|
|
||||||
impl AccountMaxSize for Realm {
|
impl AccountMaxSize for Realm {
|
||||||
fn get_max_size(&self) -> Option<usize> {
|
fn get_max_size(&self) -> Option<usize> {
|
||||||
Some(self.name.len() + 111)
|
Some(self.name.len() + 161)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +83,7 @@ impl Realm {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.council_mint == Some(*governing_token_mint) {
|
if self.config.council_mint == Some(*governing_token_mint) {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,9 +205,15 @@ mod test {
|
||||||
account_type: GovernanceAccountType::Realm,
|
account_type: GovernanceAccountType::Realm,
|
||||||
community_mint: Pubkey::new_unique(),
|
community_mint: Pubkey::new_unique(),
|
||||||
reserved: [0; 8],
|
reserved: [0; 8],
|
||||||
council_mint: Some(Pubkey::new_unique()),
|
|
||||||
authority: Some(Pubkey::new_unique()),
|
authority: Some(Pubkey::new_unique()),
|
||||||
name: "test-realm".to_string(),
|
name: "test-realm".to_string(),
|
||||||
|
config: RealmConfig {
|
||||||
|
council_mint: Some(Pubkey::new_unique()),
|
||||||
|
reserved: [0; 8],
|
||||||
|
custodian: Some(Pubkey::new_unique()),
|
||||||
|
community_mint_max_vote_weight_source: MintMaxVoteWeightSource::Absolute(100),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let size = realm.try_to_vec().unwrap().len();
|
let size = realm.try_to_vec().unwrap().len();
|
||||||
|
|
|
@ -93,7 +93,7 @@ impl TokenOwnerRecord {
|
||||||
let min_tokens_to_create_proposal =
|
let min_tokens_to_create_proposal =
|
||||||
if self.governing_token_mint == realm_data.community_mint {
|
if self.governing_token_mint == realm_data.community_mint {
|
||||||
config.min_community_tokens_to_create_proposal
|
config.min_community_tokens_to_create_proposal
|
||||||
} else if Some(self.governing_token_mint) == realm_data.council_mint {
|
} else if Some(self.governing_token_mint) == realm_data.config.council_mint {
|
||||||
config.min_council_tokens_to_create_proposal
|
config.min_council_tokens_to_create_proposal
|
||||||
} else {
|
} else {
|
||||||
return Err(GovernanceError::InvalidGoverningTokenMint.into());
|
return Err(GovernanceError::InvalidGoverningTokenMint.into());
|
||||||
|
|
|
@ -149,7 +149,8 @@ async fn test_cast_vote_with_invalid_mint_error() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Try to use Council Mint with Community Proposal
|
// Try to use Council Mint with Community Proposal
|
||||||
proposal_cookie.account.governing_token_mint = realm_cookie.account.council_mint.unwrap();
|
proposal_cookie.account.governing_token_mint =
|
||||||
|
realm_cookie.account.config.council_mint.unwrap();
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
let err = governance_test
|
let err = governance_test
|
||||||
|
|
|
@ -411,7 +411,7 @@ async fn test_create_council_proposal_using_community_tokens() {
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
realm_cookie.account.council_mint.unwrap(),
|
realm_cookie.account.config.council_mint.unwrap(),
|
||||||
proposal_account.governing_token_mint
|
proposal_account.governing_token_mint
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ async fn test_finalize_vote_to_succeeded() {
|
||||||
// Act
|
// Act
|
||||||
|
|
||||||
governance_test
|
governance_test
|
||||||
.finalize_vote(&proposal_cookie)
|
.finalize_vote(&realm_cookie, &proposal_cookie)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ async fn test_finalize_vote_to_defeated() {
|
||||||
// Act
|
// Act
|
||||||
|
|
||||||
governance_test
|
governance_test
|
||||||
.finalize_vote(&proposal_cookie)
|
.finalize_vote(&realm_cookie, &proposal_cookie)
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ async fn test_finalize_vote_with_invalid_mint_error() {
|
||||||
// Act
|
// Act
|
||||||
|
|
||||||
let err = governance_test
|
let err = governance_test
|
||||||
.finalize_vote(&proposal_cookie)
|
.finalize_vote(&realm_cookie, &proposal_cookie)
|
||||||
.await
|
.await
|
||||||
.err()
|
.err()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -270,7 +270,7 @@ async fn test_finalize_vote_with_invalid_governance_error() {
|
||||||
// Act
|
// Act
|
||||||
|
|
||||||
let err = governance_test
|
let err = governance_test
|
||||||
.finalize_vote(&proposal_cookie)
|
.finalize_vote(&realm_cookie, &proposal_cookie)
|
||||||
.await
|
.await
|
||||||
.err()
|
.err()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
@ -36,7 +36,7 @@ use spl_governance::{
|
||||||
state::{
|
state::{
|
||||||
enums::{
|
enums::{
|
||||||
GovernanceAccountType, InstructionExecutionFlags, InstructionExecutionStatus,
|
GovernanceAccountType, InstructionExecutionFlags, InstructionExecutionStatus,
|
||||||
ProposalState, VoteThresholdPercentage, VoteWeight,
|
MintMaxVoteWeightSource, ProposalState, VoteThresholdPercentage, VoteWeight,
|
||||||
},
|
},
|
||||||
governance::{
|
governance::{
|
||||||
get_account_governance_address, get_mint_governance_address,
|
get_account_governance_address, get_mint_governance_address,
|
||||||
|
@ -47,7 +47,7 @@ use spl_governance::{
|
||||||
proposal_instruction::{
|
proposal_instruction::{
|
||||||
get_proposal_instruction_address, InstructionData, ProposalInstruction,
|
get_proposal_instruction_address, InstructionData, ProposalInstruction,
|
||||||
},
|
},
|
||||||
realm::{get_governing_token_holding_address, get_realm_address, Realm},
|
realm::{get_governing_token_holding_address, get_realm_address, Realm, RealmConfig},
|
||||||
signatory_record::{get_signatory_record_address, SignatoryRecord},
|
signatory_record::{get_signatory_record_address, SignatoryRecord},
|
||||||
token_owner_record::{get_token_owner_record_address, TokenOwnerRecord},
|
token_owner_record::{get_token_owner_record_address, TokenOwnerRecord},
|
||||||
vote_record::{get_vote_record_address, VoteRecord},
|
vote_record::{get_vote_record_address, VoteRecord},
|
||||||
|
@ -185,10 +185,16 @@ impl GovernanceProgramTest {
|
||||||
let account = Realm {
|
let account = Realm {
|
||||||
account_type: GovernanceAccountType::Realm,
|
account_type: GovernanceAccountType::Realm,
|
||||||
community_mint: community_token_mint_keypair.pubkey(),
|
community_mint: community_token_mint_keypair.pubkey(),
|
||||||
council_mint: Some(council_token_mint_keypair.pubkey()),
|
|
||||||
name,
|
name,
|
||||||
reserved: [0; 8],
|
reserved: [0; 8],
|
||||||
authority: Some(realm_authority.pubkey()),
|
authority: Some(realm_authority.pubkey()),
|
||||||
|
config: RealmConfig {
|
||||||
|
council_mint: Some(council_token_mint_keypair.pubkey()),
|
||||||
|
reserved: [0; 8],
|
||||||
|
custodian: Some(realm_authority.pubkey()),
|
||||||
|
community_mint_max_vote_weight_source: MintMaxVoteWeightSource::Percentage(100),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
RealmCookie {
|
RealmCookie {
|
||||||
|
@ -210,7 +216,7 @@ impl GovernanceProgramTest {
|
||||||
self.next_realm_id += 1;
|
self.next_realm_id += 1;
|
||||||
|
|
||||||
let realm_address = get_realm_address(&self.program_id, &name);
|
let realm_address = get_realm_address(&self.program_id, &name);
|
||||||
let council_mint = realm_cookie.account.council_mint.unwrap();
|
let council_mint = realm_cookie.account.config.council_mint.unwrap();
|
||||||
|
|
||||||
let realm_authority = Keypair::new();
|
let realm_authority = Keypair::new();
|
||||||
|
|
||||||
|
@ -230,10 +236,16 @@ impl GovernanceProgramTest {
|
||||||
let account = Realm {
|
let account = Realm {
|
||||||
account_type: GovernanceAccountType::Realm,
|
account_type: GovernanceAccountType::Realm,
|
||||||
community_mint: realm_cookie.account.community_mint,
|
community_mint: realm_cookie.account.community_mint,
|
||||||
council_mint: Some(council_mint),
|
|
||||||
name,
|
name,
|
||||||
reserved: [0; 8],
|
reserved: [0; 8],
|
||||||
authority: Some(realm_authority.pubkey()),
|
authority: Some(realm_authority.pubkey()),
|
||||||
|
config: RealmConfig {
|
||||||
|
council_mint: Some(council_mint),
|
||||||
|
reserved: [0; 8],
|
||||||
|
custodian: Some(realm_authority.pubkey()),
|
||||||
|
community_mint_max_vote_weight_source: MintMaxVoteWeightSource::Percentage(100),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
let community_token_holding_address = get_governing_token_holding_address(
|
let community_token_holding_address = get_governing_token_holding_address(
|
||||||
|
@ -315,7 +327,7 @@ impl GovernanceProgramTest {
|
||||||
) {
|
) {
|
||||||
self.with_subsequent_governing_token_deposit(
|
self.with_subsequent_governing_token_deposit(
|
||||||
&realm_cookie.address,
|
&realm_cookie.address,
|
||||||
&realm_cookie.account.council_mint.unwrap(),
|
&realm_cookie.account.config.council_mint.unwrap(),
|
||||||
realm_cookie.council_mint_authority.as_ref().unwrap(),
|
realm_cookie.council_mint_authority.as_ref().unwrap(),
|
||||||
token_owner_record_cookie,
|
token_owner_record_cookie,
|
||||||
amount,
|
amount,
|
||||||
|
@ -331,7 +343,7 @@ impl GovernanceProgramTest {
|
||||||
) -> TokeOwnerRecordCookie {
|
) -> TokeOwnerRecordCookie {
|
||||||
self.with_initial_governing_token_deposit(
|
self.with_initial_governing_token_deposit(
|
||||||
&realm_cookie.address,
|
&realm_cookie.address,
|
||||||
&realm_cookie.account.council_mint.unwrap(),
|
&realm_cookie.account.config.council_mint.unwrap(),
|
||||||
&realm_cookie.council_mint_authority.as_ref().unwrap(),
|
&realm_cookie.council_mint_authority.as_ref().unwrap(),
|
||||||
amount,
|
amount,
|
||||||
)
|
)
|
||||||
|
@ -345,7 +357,7 @@ impl GovernanceProgramTest {
|
||||||
) -> TokeOwnerRecordCookie {
|
) -> TokeOwnerRecordCookie {
|
||||||
self.with_initial_governing_token_deposit(
|
self.with_initial_governing_token_deposit(
|
||||||
&realm_cookie.address,
|
&realm_cookie.address,
|
||||||
&realm_cookie.account.council_mint.unwrap(),
|
&realm_cookie.account.config.council_mint.unwrap(),
|
||||||
realm_cookie.council_mint_authority.as_ref().unwrap(),
|
realm_cookie.council_mint_authority.as_ref().unwrap(),
|
||||||
100,
|
100,
|
||||||
)
|
)
|
||||||
|
@ -502,7 +514,7 @@ impl GovernanceProgramTest {
|
||||||
) {
|
) {
|
||||||
self.with_governing_token_governance_delegate(
|
self.with_governing_token_governance_delegate(
|
||||||
realm_cookie,
|
realm_cookie,
|
||||||
&realm_cookie.account.council_mint.unwrap(),
|
&realm_cookie.account.config.council_mint.unwrap(),
|
||||||
token_owner_record_cookie,
|
token_owner_record_cookie,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
@ -618,7 +630,7 @@ impl GovernanceProgramTest {
|
||||||
self.withdraw_governing_tokens(
|
self.withdraw_governing_tokens(
|
||||||
realm_cookie,
|
realm_cookie,
|
||||||
token_owner_record_cookie,
|
token_owner_record_cookie,
|
||||||
&realm_cookie.account.council_mint.unwrap(),
|
&realm_cookie.account.config.council_mint.unwrap(),
|
||||||
&token_owner_record_cookie.token_owner,
|
&token_owner_record_cookie.token_owner,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
@ -1263,10 +1275,12 @@ impl GovernanceProgramTest {
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub async fn finalize_vote(
|
pub async fn finalize_vote(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
realm_cookie: &RealmCookie,
|
||||||
proposal_cookie: &ProposalCookie,
|
proposal_cookie: &ProposalCookie,
|
||||||
) -> Result<(), ProgramError> {
|
) -> Result<(), ProgramError> {
|
||||||
let finalize_vote_instruction = finalize_vote(
|
let finalize_vote_instruction = finalize_vote(
|
||||||
&self.program_id,
|
&self.program_id,
|
||||||
|
&realm_cookie.address,
|
||||||
&proposal_cookie.account.governance,
|
&proposal_cookie.account.governance,
|
||||||
&proposal_cookie.address,
|
&proposal_cookie.address,
|
||||||
&proposal_cookie.account.governing_token_mint,
|
&proposal_cookie.account.governing_token_mint,
|
||||||
|
@ -1351,6 +1365,7 @@ impl GovernanceProgramTest {
|
||||||
) -> Result<VoteRecordCookie, ProgramError> {
|
) -> Result<VoteRecordCookie, ProgramError> {
|
||||||
let vote_instruction = cast_vote(
|
let vote_instruction = cast_vote(
|
||||||
&self.program_id,
|
&self.program_id,
|
||||||
|
&token_owner_record_cookie.account.realm,
|
||||||
&proposal_cookie.account.governance,
|
&proposal_cookie.account.governance,
|
||||||
&proposal_cookie.address,
|
&proposal_cookie.address,
|
||||||
&token_owner_record_cookie.address,
|
&token_owner_record_cookie.address,
|
||||||
|
|
Loading…
Reference in New Issue