Governance: Voter-weight-addin cleanup (#2512)
* chore: Ensure voter-weight-addin is built for tests fix: build addin during test run fix: build voter weight addin for tests using the addin only chore: use mutex to build addin only once chore: move build guard to separate file chore: update governance version for chat * chore: create tools crate for common utility functions in governance ecosystem * chore: add test-sdk and tools readme * chore: rename reserved addins to specific names * chore: remove todo comment * chore: remove unnecessary var drop * chore: move all account tools to shared crate * chore: fix chat compilation * chore: move program_id to first position
This commit is contained in:
parent
f95e390dd4
commit
d6d0b92ae7
|
@ -3674,13 +3674,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spl-governance"
|
name = "spl-governance"
|
||||||
version = "2.1.1"
|
version = "2.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"arrayref",
|
"arrayref",
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
"base64 0.13.0",
|
"base64 0.13.0",
|
||||||
"bincode",
|
"bincode",
|
||||||
"borsh",
|
"borsh",
|
||||||
|
"lazy_static",
|
||||||
"num-derive",
|
"num-derive",
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"proptest",
|
"proptest",
|
||||||
|
@ -3691,6 +3692,7 @@ dependencies = [
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"spl-governance 1.1.1",
|
"spl-governance 1.1.1",
|
||||||
"spl-governance-test-sdk",
|
"spl-governance-test-sdk",
|
||||||
|
"spl-governance-tools",
|
||||||
"spl-token 3.2.0",
|
"spl-token 3.2.0",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -3712,8 +3714,9 @@ dependencies = [
|
||||||
"solana-program",
|
"solana-program",
|
||||||
"solana-program-test",
|
"solana-program-test",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"spl-governance 2.1.1",
|
"spl-governance 2.1.2",
|
||||||
"spl-governance-test-sdk",
|
"spl-governance-test-sdk",
|
||||||
|
"spl-governance-tools",
|
||||||
"spl-token 3.2.0",
|
"spl-token 3.2.0",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -3736,6 +3739,22 @@ dependencies = [
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "spl-governance-tools"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"arrayref",
|
||||||
|
"bincode",
|
||||||
|
"borsh",
|
||||||
|
"num-derive",
|
||||||
|
"num-traits",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"solana-program",
|
||||||
|
"spl-token 3.2.0",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "spl-governance-voter-weight-addin"
|
name = "spl-governance-voter-weight-addin"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -3753,9 +3772,9 @@ dependencies = [
|
||||||
"solana-program",
|
"solana-program",
|
||||||
"solana-program-test",
|
"solana-program-test",
|
||||||
"solana-sdk",
|
"solana-sdk",
|
||||||
"spl-governance 2.1.1",
|
"spl-governance 2.1.2",
|
||||||
"spl-governance-chat",
|
|
||||||
"spl-governance-test-sdk",
|
"spl-governance-test-sdk",
|
||||||
|
"spl-governance-tools",
|
||||||
"spl-token 3.2.0",
|
"spl-token 3.2.0",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
|
@ -13,6 +13,7 @@ members = [
|
||||||
"governance/voter-weight-addin/program",
|
"governance/voter-weight-addin/program",
|
||||||
"governance/program",
|
"governance/program",
|
||||||
"governance/test-sdk",
|
"governance/test-sdk",
|
||||||
|
"governance/tools",
|
||||||
"governance/chat/program",
|
"governance/chat/program",
|
||||||
"libraries/math",
|
"libraries/math",
|
||||||
"memo/program",
|
"memo/program",
|
||||||
|
|
|
@ -21,7 +21,8 @@ serde = "1.0.127"
|
||||||
serde_derive = "1.0.103"
|
serde_derive = "1.0.103"
|
||||||
solana-program = "1.8.0"
|
solana-program = "1.8.0"
|
||||||
spl-token = { version = "3.2", path = "../../../token/program", features = [ "no-entrypoint" ] }
|
spl-token = { version = "3.2", path = "../../../token/program", features = [ "no-entrypoint" ] }
|
||||||
spl-governance= { version = "2.1.0", path ="../../program", features = [ "no-entrypoint" ]}
|
spl-governance= { version = "2.1.2", path ="../../program", features = [ "no-entrypoint" ]}
|
||||||
|
spl-governance-tools= { version = "0.1.0", path ="../../tools"}
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ pub mod error;
|
||||||
pub mod instruction;
|
pub mod instruction;
|
||||||
pub mod processor;
|
pub mod processor;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod tools;
|
|
||||||
|
|
||||||
// Export current sdk types for downstream users building with a different sdk version
|
// Export current sdk types for downstream users building with a different sdk version
|
||||||
pub use solana_program;
|
pub use solana_program;
|
||||||
|
|
|
@ -4,7 +4,6 @@ use crate::{
|
||||||
error::GovernanceChatError,
|
error::GovernanceChatError,
|
||||||
instruction::GovernanceChatInstruction,
|
instruction::GovernanceChatInstruction,
|
||||||
state::{assert_is_valid_chat_message, ChatMessage, GovernanceChatAccountType, MessageBody},
|
state::{assert_is_valid_chat_message, ChatMessage, GovernanceChatAccountType, MessageBody},
|
||||||
tools::account::create_and_serialize_account,
|
|
||||||
};
|
};
|
||||||
use borsh::BorshDeserialize;
|
use borsh::BorshDeserialize;
|
||||||
|
|
||||||
|
@ -21,6 +20,7 @@ use spl_governance::state::{
|
||||||
governance::get_governance_data, proposal::get_proposal_data_for_governance,
|
governance::get_governance_data, proposal::get_proposal_data_for_governance,
|
||||||
token_owner_record::get_token_owner_record_data_for_realm,
|
token_owner_record::get_token_owner_record_data_for_realm,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account;
|
||||||
|
|
||||||
/// Processes an instruction
|
/// Processes an instruction
|
||||||
pub fn process_instruction(
|
pub fn process_instruction(
|
||||||
|
|
|
@ -4,7 +4,8 @@ use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, clock::UnixTimestamp, program_error::ProgramError, pubkey::Pubkey,
|
account_info::AccountInfo, clock::UnixTimestamp, program_error::ProgramError, pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
use spl_governance::tools::account::{assert_is_valid_account, AccountMaxSize};
|
|
||||||
|
use spl_governance_tools::account::{assert_is_valid_account, AccountMaxSize};
|
||||||
|
|
||||||
/// Defines all GovernanceChat accounts types
|
/// Defines all GovernanceChat accounts types
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
@ -1,62 +0,0 @@
|
||||||
//! General purpose account utility functions
|
|
||||||
|
|
||||||
use borsh::BorshSerialize;
|
|
||||||
use solana_program::{
|
|
||||||
account_info::AccountInfo, program::invoke, program_error::ProgramError, pubkey::Pubkey,
|
|
||||||
rent::Rent, system_instruction::create_account, system_program, sysvar::Sysvar,
|
|
||||||
};
|
|
||||||
use spl_governance::tools::account::AccountMaxSize;
|
|
||||||
|
|
||||||
use crate::error::GovernanceChatError;
|
|
||||||
|
|
||||||
/// Creates a new account and serializes data into it using AccountMaxSize to determine the account's size
|
|
||||||
pub fn create_and_serialize_account<'a, T: BorshSerialize + AccountMaxSize>(
|
|
||||||
payer_info: &AccountInfo<'a>,
|
|
||||||
account_info: &AccountInfo<'a>,
|
|
||||||
account_data: &T,
|
|
||||||
program_id: &Pubkey,
|
|
||||||
system_info: &AccountInfo<'a>,
|
|
||||||
) -> Result<(), ProgramError> {
|
|
||||||
// Assert the account is not initialized yet
|
|
||||||
if !(account_info.data_is_empty() && *account_info.owner == system_program::id()) {
|
|
||||||
return Err(GovernanceChatError::AccountAlreadyInitialized.into());
|
|
||||||
}
|
|
||||||
|
|
||||||
let (serialized_data, account_size) = if let Some(max_size) = account_data.get_max_size() {
|
|
||||||
(None, max_size)
|
|
||||||
} else {
|
|
||||||
let serialized_data = account_data.try_to_vec()?;
|
|
||||||
let account_size = serialized_data.len();
|
|
||||||
(Some(serialized_data), account_size)
|
|
||||||
};
|
|
||||||
|
|
||||||
let rent = Rent::get()?;
|
|
||||||
|
|
||||||
let create_account_instruction = create_account(
|
|
||||||
payer_info.key,
|
|
||||||
account_info.key,
|
|
||||||
rent.minimum_balance(account_size),
|
|
||||||
account_size as u64,
|
|
||||||
program_id,
|
|
||||||
);
|
|
||||||
|
|
||||||
invoke(
|
|
||||||
&create_account_instruction,
|
|
||||||
&[
|
|
||||||
payer_info.clone(),
|
|
||||||
account_info.clone(),
|
|
||||||
system_info.clone(),
|
|
||||||
],
|
|
||||||
)?;
|
|
||||||
|
|
||||||
if let Some(serialized_data) = serialized_data {
|
|
||||||
account_info
|
|
||||||
.data
|
|
||||||
.borrow_mut()
|
|
||||||
.copy_from_slice(&serialized_data);
|
|
||||||
} else {
|
|
||||||
account_data.serialize(&mut *account_info.data.borrow_mut())?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
//! Utility functions
|
|
||||||
|
|
||||||
pub mod account;
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "spl-governance"
|
name = "spl-governance"
|
||||||
version = "2.1.1"
|
version = "2.1.2"
|
||||||
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"
|
||||||
|
@ -21,17 +21,18 @@ serde = "1.0.130"
|
||||||
serde_derive = "1.0.103"
|
serde_derive = "1.0.103"
|
||||||
solana-program = "1.8.0"
|
solana-program = "1.8.0"
|
||||||
spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] }
|
spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] }
|
||||||
|
spl-governance-tools= { version = "0.1.0", path ="../tools"}
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
assert_matches = "1.5.0"
|
assert_matches = "1.5.0"
|
||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
proptest = "1.0"
|
proptest = "1.0"
|
||||||
solana-program-test = "1.8.0"
|
solana-program-test = "1.8.0"
|
||||||
solana-sdk = "1.8.0"
|
solana-sdk = "1.8.0"
|
||||||
spl-governance-test-sdk = { version = "0.1.0", path ="../test-sdk"}
|
spl-governance-test-sdk = { version = "0.1.0", path ="../test-sdk"}
|
||||||
spl-governance-v1 = {package="spl-governance", version = "1.1.1", features = [ "no-entrypoint" ] }
|
spl-governance-v1 = {package="spl-governance", version = "1.1.1", features = [ "no-entrypoint" ] }
|
||||||
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib", "lib"]
|
crate-type = ["cdylib", "lib"]
|
||||||
|
|
|
@ -9,12 +9,9 @@ use solana_program::{
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::{get_account_data, AccountMaxSize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{error::GovernanceError, state::token_owner_record::TokenOwnerRecord};
|
||||||
error::GovernanceError,
|
|
||||||
state::token_owner_record::TokenOwnerRecord,
|
|
||||||
tools::account::{get_account_data, AccountMaxSize},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// VoterWeight account type
|
/// VoterWeight account type
|
||||||
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
|
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
|
||||||
|
@ -82,7 +79,7 @@ pub fn get_voter_weight_record_data(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
voter_weight_record_info: &AccountInfo,
|
voter_weight_record_info: &AccountInfo,
|
||||||
) -> Result<VoterWeightRecord, ProgramError> {
|
) -> Result<VoterWeightRecord, ProgramError> {
|
||||||
get_account_data::<VoterWeightRecord>(voter_weight_record_info, program_id)
|
get_account_data::<VoterWeightRecord>(program_id, voter_weight_record_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes VoterWeightRecord account, checks owner program and asserts it's for the same realm, mint and token owner as the provided TokenOwnerRecord
|
/// Deserializes VoterWeightRecord account, checks owner program and asserts it's for the same realm, mint and token owner as the provided TokenOwnerRecord
|
||||||
|
|
|
@ -162,20 +162,6 @@ pub enum GovernanceError {
|
||||||
#[error("Invalid Signatory Mint")]
|
#[error("Invalid Signatory Mint")]
|
||||||
InvalidSignatoryMint,
|
InvalidSignatoryMint,
|
||||||
|
|
||||||
/// ---- Account Tools Errors ----
|
|
||||||
|
|
||||||
/// Invalid account owner
|
|
||||||
#[error("Invalid account owner")]
|
|
||||||
InvalidAccountOwner,
|
|
||||||
|
|
||||||
/// Account doesn't exist
|
|
||||||
#[error("Account doesn't exist")]
|
|
||||||
AccountDoesNotExist,
|
|
||||||
|
|
||||||
/// Invalid Account type
|
|
||||||
#[error("Invalid Account type")]
|
|
||||||
InvalidAccountType,
|
|
||||||
|
|
||||||
/// Proposal does not belong to the given Governance
|
/// Proposal does not belong to the given Governance
|
||||||
#[error("Proposal does not belong to the given Governance")]
|
#[error("Proposal does not belong to the given Governance")]
|
||||||
InvalidGovernanceForProposal,
|
InvalidGovernanceForProposal,
|
||||||
|
|
|
@ -8,15 +8,13 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
use crate::{
|
use crate::state::{
|
||||||
state::{
|
|
||||||
enums::GovernanceAccountType,
|
enums::GovernanceAccountType,
|
||||||
proposal::get_proposal_data,
|
proposal::get_proposal_data,
|
||||||
signatory_record::{get_signatory_record_address_seeds, SignatoryRecord},
|
signatory_record::{get_signatory_record_address_seeds, SignatoryRecord},
|
||||||
token_owner_record::get_token_owner_record_data_for_proposal_owner,
|
token_owner_record::get_token_owner_record_data_for_proposal_owner,
|
||||||
},
|
|
||||||
tools::account::create_and_serialize_account_signed,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes AddSignatory instruction
|
/// Processes AddSignatory instruction
|
||||||
|
|
|
@ -8,6 +8,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
|
@ -23,7 +24,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
vote_record::{get_vote_record_address_seeds, VoteRecord},
|
vote_record::{get_vote_record_address_seeds, VoteRecord},
|
||||||
},
|
},
|
||||||
tools::{account::create_and_serialize_account_signed, spl_token::get_spl_token_mint_supply},
|
tools::spl_token::get_spl_token_mint_supply,
|
||||||
};
|
};
|
||||||
|
|
||||||
use borsh::BorshSerialize;
|
use borsh::BorshSerialize;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
//! Program state processor
|
//! Program state processor
|
||||||
|
|
||||||
use crate::{
|
use crate::state::{
|
||||||
state::{
|
|
||||||
enums::GovernanceAccountType,
|
enums::GovernanceAccountType,
|
||||||
governance::{
|
governance::{
|
||||||
assert_valid_create_governance_args, get_account_governance_address_seeds, Governance,
|
assert_valid_create_governance_args, get_account_governance_address_seeds, Governance,
|
||||||
|
@ -9,8 +8,6 @@ use crate::{
|
||||||
},
|
},
|
||||||
realm::get_realm_data,
|
realm::get_realm_data,
|
||||||
token_owner_record::get_token_owner_record_data_for_realm,
|
token_owner_record::get_token_owner_record_data_for_realm,
|
||||||
},
|
|
||||||
tools::account::create_and_serialize_account_signed,
|
|
||||||
};
|
};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::{next_account_info, AccountInfo},
|
account_info::{next_account_info, AccountInfo},
|
||||||
|
@ -19,6 +16,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
/// Processes CreateAccountGovernance instruction
|
/// Processes CreateAccountGovernance instruction
|
||||||
pub fn process_create_account_governance(
|
pub fn process_create_account_governance(
|
||||||
|
|
|
@ -10,10 +10,7 @@ use crate::{
|
||||||
realm::get_realm_data,
|
realm::get_realm_data,
|
||||||
token_owner_record::get_token_owner_record_data_for_realm,
|
token_owner_record::get_token_owner_record_data_for_realm,
|
||||||
},
|
},
|
||||||
tools::{
|
tools::spl_token::{assert_spl_token_mint_authority_is_signer, set_spl_token_mint_authority},
|
||||||
account::create_and_serialize_account_signed,
|
|
||||||
spl_token::{assert_spl_token_mint_authority_is_signer, set_spl_token_mint_authority},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::{next_account_info, AccountInfo},
|
account_info::{next_account_info, AccountInfo},
|
||||||
|
@ -22,6 +19,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
/// Processes CreateMintGovernance instruction
|
/// Processes CreateMintGovernance instruction
|
||||||
pub fn process_create_mint_governance(
|
pub fn process_create_mint_governance(
|
||||||
|
|
|
@ -11,12 +11,9 @@ use crate::{
|
||||||
realm::get_realm_data,
|
realm::get_realm_data,
|
||||||
token_owner_record::get_token_owner_record_data_for_realm,
|
token_owner_record::get_token_owner_record_data_for_realm,
|
||||||
},
|
},
|
||||||
tools::{
|
tools::bpf_loader_upgradeable::{
|
||||||
account::create_and_serialize_account_signed,
|
|
||||||
bpf_loader_upgradeable::{
|
|
||||||
assert_program_upgrade_authority_is_signer, set_program_upgrade_authority,
|
assert_program_upgrade_authority_is_signer, set_program_upgrade_authority,
|
||||||
},
|
},
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::{next_account_info, AccountInfo},
|
account_info::{next_account_info, AccountInfo},
|
||||||
|
@ -25,6 +22,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
/// Processes CreateProgramGovernance instruction
|
/// Processes CreateProgramGovernance instruction
|
||||||
pub fn process_create_program_governance(
|
pub fn process_create_program_governance(
|
||||||
|
|
|
@ -9,6 +9,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
|
@ -19,7 +20,6 @@ use crate::{
|
||||||
realm::get_realm_data_for_governing_token_mint,
|
realm::get_realm_data_for_governing_token_mint,
|
||||||
token_owner_record::get_token_owner_record_data_for_realm,
|
token_owner_record::get_token_owner_record_data_for_realm,
|
||||||
},
|
},
|
||||||
tools::account::create_and_serialize_account_signed,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes CreateProposal instruction
|
/// Processes CreateProposal instruction
|
||||||
|
|
|
@ -7,6 +7,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
|
@ -18,9 +19,7 @@ use crate::{
|
||||||
},
|
},
|
||||||
realm_config::{get_realm_config_address_seeds, RealmConfigAccount},
|
realm_config::{get_realm_config_address_seeds, RealmConfigAccount},
|
||||||
},
|
},
|
||||||
tools::{
|
tools::spl_token::create_spl_token_account_signed,
|
||||||
account::create_and_serialize_account_signed, spl_token::create_spl_token_account_signed,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes CreateRealm instruction
|
/// Processes CreateRealm instruction
|
||||||
|
@ -92,9 +91,9 @@ pub fn process_create_realm(
|
||||||
account_type: GovernanceAccountType::RealmConfig,
|
account_type: GovernanceAccountType::RealmConfig,
|
||||||
realm: *realm_info.key,
|
realm: *realm_info.key,
|
||||||
community_voter_weight_addin: Some(*community_voter_weight_addin_info.key),
|
community_voter_weight_addin: Some(*community_voter_weight_addin_info.key),
|
||||||
reserved_1: None,
|
community_max_vote_weight_addin: None,
|
||||||
reserved_2: None,
|
council_voter_weight_addin: None,
|
||||||
reserved_3: None,
|
council_max_vote_weight_addin: None,
|
||||||
reserved: [0; 128],
|
reserved: [0; 128],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -10,10 +10,7 @@ use crate::{
|
||||||
realm::get_realm_data,
|
realm::get_realm_data,
|
||||||
token_owner_record::get_token_owner_record_data_for_realm,
|
token_owner_record::get_token_owner_record_data_for_realm,
|
||||||
},
|
},
|
||||||
tools::{
|
tools::spl_token::{assert_spl_token_owner_is_signer, set_spl_token_owner},
|
||||||
account::create_and_serialize_account_signed,
|
|
||||||
spl_token::{assert_spl_token_owner_is_signer, set_spl_token_owner},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::{next_account_info, AccountInfo},
|
account_info::{next_account_info, AccountInfo},
|
||||||
|
@ -22,6 +19,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
/// Processes CreateTokenGovernance instruction
|
/// Processes CreateTokenGovernance instruction
|
||||||
pub fn process_create_token_governance(
|
pub fn process_create_token_governance(
|
||||||
|
|
|
@ -7,6 +7,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
|
@ -15,7 +16,6 @@ use crate::{
|
||||||
realm::get_realm_data,
|
realm::get_realm_data,
|
||||||
token_owner_record::{get_token_owner_record_address_seeds, TokenOwnerRecord},
|
token_owner_record::{get_token_owner_record_address_seeds, TokenOwnerRecord},
|
||||||
},
|
},
|
||||||
tools::account::create_and_serialize_account_signed,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes CreateTokenOwnerRecord instruction
|
/// Processes CreateTokenOwnerRecord instruction
|
||||||
|
|
|
@ -8,6 +8,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
|
@ -19,10 +20,7 @@ use crate::{
|
||||||
TokenOwnerRecord,
|
TokenOwnerRecord,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tools::{
|
tools::spl_token::{get_spl_token_mint, get_spl_token_owner, transfer_spl_tokens},
|
||||||
account::create_and_serialize_account_signed,
|
|
||||||
spl_token::{get_spl_token_mint, get_spl_token_owner, transfer_spl_tokens},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes DepositGoverningTokens instruction
|
/// Processes DepositGoverningTokens instruction
|
||||||
|
|
|
@ -10,6 +10,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
|
@ -22,7 +23,6 @@ use crate::{
|
||||||
},
|
},
|
||||||
token_owner_record::get_token_owner_record_data_for_proposal_owner,
|
token_owner_record::get_token_owner_record_data_for_proposal_owner,
|
||||||
},
|
},
|
||||||
tools::account::create_and_serialize_account_signed,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes InsertInstruction instruction
|
/// Processes InsertInstruction instruction
|
||||||
|
|
|
@ -5,16 +5,14 @@ use solana_program::{
|
||||||
entrypoint::ProgramResult,
|
entrypoint::ProgramResult,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::dispose_account;
|
||||||
|
|
||||||
use crate::{
|
use crate::state::{
|
||||||
state::{
|
|
||||||
enums::{ProposalState, VoteWeight},
|
enums::{ProposalState, VoteWeight},
|
||||||
governance::get_governance_data,
|
governance::get_governance_data,
|
||||||
proposal::get_proposal_data_for_governance_and_governing_mint,
|
proposal::get_proposal_data_for_governance_and_governing_mint,
|
||||||
token_owner_record::get_token_owner_record_data_for_realm_and_governing_mint,
|
token_owner_record::get_token_owner_record_data_for_realm_and_governing_mint,
|
||||||
vote_record::get_vote_record_data_for_proposal_and_token_owner,
|
vote_record::get_vote_record_data_for_proposal_and_token_owner,
|
||||||
},
|
|
||||||
tools::account::dispose_account,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use borsh::BorshSerialize;
|
use borsh::BorshSerialize;
|
||||||
|
|
|
@ -6,14 +6,11 @@ use solana_program::{
|
||||||
entrypoint::ProgramResult,
|
entrypoint::ProgramResult,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::dispose_account;
|
||||||
|
|
||||||
use crate::{
|
use crate::state::{
|
||||||
state::{
|
proposal::get_proposal_data, proposal_instruction::assert_proposal_instruction_for_proposal,
|
||||||
proposal::get_proposal_data,
|
|
||||||
proposal_instruction::assert_proposal_instruction_for_proposal,
|
|
||||||
token_owner_record::get_token_owner_record_data_for_proposal_owner,
|
token_owner_record::get_token_owner_record_data_for_proposal_owner,
|
||||||
},
|
|
||||||
tools::account::dispose_account,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes RemoveInstruction instruction
|
/// Processes RemoveInstruction instruction
|
||||||
|
|
|
@ -6,13 +6,11 @@ use solana_program::{
|
||||||
entrypoint::ProgramResult,
|
entrypoint::ProgramResult,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::dispose_account;
|
||||||
|
|
||||||
use crate::{
|
use crate::state::{
|
||||||
state::{
|
|
||||||
proposal::get_proposal_data, signatory_record::get_signatory_record_data_for_seeds,
|
proposal::get_proposal_data, signatory_record::get_signatory_record_data_for_seeds,
|
||||||
token_owner_record::get_token_owner_record_data_for_proposal_owner,
|
token_owner_record::get_token_owner_record_data_for_proposal_owner,
|
||||||
},
|
|
||||||
tools::account::dispose_account,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes RemoveSignatory instruction
|
/// Processes RemoveSignatory instruction
|
||||||
|
|
|
@ -8,6 +8,7 @@ use solana_program::{
|
||||||
rent::Rent,
|
rent::Rent,
|
||||||
sysvar::Sysvar,
|
sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account_signed;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
|
@ -18,7 +19,6 @@ use crate::{
|
||||||
get_realm_config_address_seeds, get_realm_config_data_for_realm, RealmConfigAccount,
|
get_realm_config_address_seeds, get_realm_config_data_for_realm, RealmConfigAccount,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tools::account::create_and_serialize_account_signed,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Processes SetRealmConfig instruction
|
/// Processes SetRealmConfig instruction
|
||||||
|
@ -77,9 +77,9 @@ pub fn process_set_realm_config(
|
||||||
account_type: GovernanceAccountType::RealmConfig,
|
account_type: GovernanceAccountType::RealmConfig,
|
||||||
realm: *realm_info.key,
|
realm: *realm_info.key,
|
||||||
community_voter_weight_addin: Some(*community_voter_weight_addin_info.key),
|
community_voter_weight_addin: Some(*community_voter_weight_addin_info.key),
|
||||||
reserved_1: None,
|
community_max_vote_weight_addin: None,
|
||||||
reserved_2: None,
|
council_voter_weight_addin: None,
|
||||||
reserved_3: None,
|
council_max_vote_weight_addin: None,
|
||||||
reserved: [0; 128],
|
reserved: [0; 128],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -6,13 +6,16 @@ use crate::{
|
||||||
enums::{GovernanceAccountType, VoteThresholdPercentage, VoteWeightSource},
|
enums::{GovernanceAccountType, VoteThresholdPercentage, VoteWeightSource},
|
||||||
realm::assert_is_valid_realm,
|
realm::assert_is_valid_realm,
|
||||||
},
|
},
|
||||||
tools::account::{get_account_data, AccountMaxSize},
|
|
||||||
};
|
};
|
||||||
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized,
|
account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::{
|
||||||
|
account::{get_account_data, AccountMaxSize},
|
||||||
|
error::GovernanceToolsError,
|
||||||
|
};
|
||||||
|
|
||||||
/// Governance config
|
/// Governance config
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -94,7 +97,7 @@ impl Governance {
|
||||||
GovernanceAccountType::TokenGovernance => {
|
GovernanceAccountType::TokenGovernance => {
|
||||||
get_token_governance_address_seeds(&self.realm, &self.governed_account)
|
get_token_governance_address_seeds(&self.realm, &self.governed_account)
|
||||||
}
|
}
|
||||||
_ => return Err(GovernanceError::InvalidAccountType.into()),
|
_ => return Err(GovernanceToolsError::InvalidAccountType.into()),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(seeds)
|
Ok(seeds)
|
||||||
|
@ -106,7 +109,7 @@ pub fn get_governance_data(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
governance_info: &AccountInfo,
|
governance_info: &AccountInfo,
|
||||||
) -> Result<Governance, ProgramError> {
|
) -> Result<Governance, ProgramError> {
|
||||||
get_account_data::<Governance>(governance_info, program_id)
|
get_account_data::<Governance>(program_id, governance_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes Governance account, checks owner program and asserts governance belongs to the given ream
|
/// Deserializes Governance account, checks owner program and asserts governance belongs to the given ream
|
||||||
|
|
|
@ -6,6 +6,7 @@ use solana_program::{
|
||||||
account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized,
|
account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::{get_account_data, AccountMaxSize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
|
@ -18,7 +19,6 @@ use crate::{
|
||||||
proposal_instruction::ProposalInstruction,
|
proposal_instruction::ProposalInstruction,
|
||||||
realm::Realm,
|
realm::Realm,
|
||||||
},
|
},
|
||||||
tools::account::{get_account_data, AccountMaxSize},
|
|
||||||
PROGRAM_AUTHORITY_SEED,
|
PROGRAM_AUTHORITY_SEED,
|
||||||
};
|
};
|
||||||
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
||||||
|
@ -450,7 +450,7 @@ pub fn get_proposal_data(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
proposal_info: &AccountInfo,
|
proposal_info: &AccountInfo,
|
||||||
) -> Result<Proposal, ProgramError> {
|
) -> Result<Proposal, ProgramError> {
|
||||||
get_account_data::<Proposal>(proposal_info, program_id)
|
get_account_data::<Proposal>(program_id, proposal_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes Proposal and validates it belongs to the given Governance and Governing Mint
|
/// Deserializes Proposal and validates it belongs to the given Governance and Governing Mint
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
state::enums::{GovernanceAccountType, InstructionExecutionStatus},
|
state::enums::{GovernanceAccountType, InstructionExecutionStatus},
|
||||||
tools::account::{get_account_data, AccountMaxSize},
|
|
||||||
PROGRAM_AUTHORITY_SEED,
|
PROGRAM_AUTHORITY_SEED,
|
||||||
};
|
};
|
||||||
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
||||||
|
@ -15,6 +14,7 @@ use solana_program::{
|
||||||
program_pack::IsInitialized,
|
program_pack::IsInitialized,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::{get_account_data, AccountMaxSize};
|
||||||
|
|
||||||
/// InstructionData wrapper. It can be removed once Borsh serialization for Instruction is supported in the SDK
|
/// InstructionData wrapper. It can be removed once Borsh serialization for Instruction is supported in the SDK
|
||||||
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
|
#[derive(Clone, Debug, PartialEq, BorshDeserialize, BorshSerialize, BorshSchema)]
|
||||||
|
@ -146,7 +146,7 @@ pub fn get_proposal_instruction_data(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
proposal_instruction_info: &AccountInfo,
|
proposal_instruction_info: &AccountInfo,
|
||||||
) -> Result<ProposalInstruction, ProgramError> {
|
) -> Result<ProposalInstruction, ProgramError> {
|
||||||
get_account_data::<ProposalInstruction>(proposal_instruction_info, program_id)
|
get_account_data::<ProposalInstruction>(program_id, proposal_instruction_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes and returns ProposalInstruction account and checks it belongs to the given Proposal
|
/// Deserializes and returns ProposalInstruction account and checks it belongs to the given Proposal
|
||||||
|
|
|
@ -5,11 +5,11 @@ use solana_program::{
|
||||||
account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized,
|
account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::{assert_is_valid_account, get_account_data, AccountMaxSize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error::GovernanceError,
|
error::GovernanceError,
|
||||||
state::enums::{GovernanceAccountType, MintMaxVoteWeightSource},
|
state::enums::{GovernanceAccountType, MintMaxVoteWeightSource},
|
||||||
tools::account::{assert_is_valid_account, get_account_data, AccountMaxSize},
|
|
||||||
PROGRAM_AUTHORITY_SEED,
|
PROGRAM_AUTHORITY_SEED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -155,7 +155,7 @@ pub fn get_realm_data(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
realm_info: &AccountInfo,
|
realm_info: &AccountInfo,
|
||||||
) -> Result<Realm, ProgramError> {
|
) -> Result<Realm, ProgramError> {
|
||||||
get_account_data::<Realm>(realm_info, program_id)
|
get_account_data::<Realm>(program_id, realm_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes account and checks the given authority is Realm's authority
|
/// Deserializes account and checks the given authority is Realm's authority
|
||||||
|
@ -164,7 +164,7 @@ pub fn get_realm_data_for_authority(
|
||||||
realm_info: &AccountInfo,
|
realm_info: &AccountInfo,
|
||||||
realm_authority: &Pubkey,
|
realm_authority: &Pubkey,
|
||||||
) -> Result<Realm, ProgramError> {
|
) -> Result<Realm, ProgramError> {
|
||||||
let realm_data = get_account_data::<Realm>(realm_info, program_id)?;
|
let realm_data = get_account_data::<Realm>(program_id, realm_info)?;
|
||||||
|
|
||||||
if realm_data.authority.is_none() {
|
if realm_data.authority.is_none() {
|
||||||
return Err(GovernanceError::RealmHasNoAuthority.into());
|
return Err(GovernanceError::RealmHasNoAuthority.into());
|
||||||
|
|
|
@ -6,12 +6,9 @@ use solana_program::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
||||||
|
use spl_governance_tools::account::{get_account_data, AccountMaxSize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{error::GovernanceError, state::enums::GovernanceAccountType};
|
||||||
error::GovernanceError,
|
|
||||||
state::enums::GovernanceAccountType,
|
|
||||||
tools::account::{get_account_data, AccountMaxSize},
|
|
||||||
};
|
|
||||||
|
|
||||||
/// RealmConfig account
|
/// RealmConfig account
|
||||||
/// The account is an optional extension to RealmConfig stored on Realm account
|
/// The account is an optional extension to RealmConfig stored on Realm account
|
||||||
|
@ -26,14 +23,17 @@ pub struct RealmConfigAccount {
|
||||||
/// Addin providing voter weights for community token
|
/// Addin providing voter weights for community token
|
||||||
pub community_voter_weight_addin: Option<Pubkey>,
|
pub community_voter_weight_addin: Option<Pubkey>,
|
||||||
|
|
||||||
/// Reserved for community max vote weight addin
|
/// Addin providing max vote weight for community token
|
||||||
pub reserved_1: Option<Pubkey>,
|
/// Note: This field is not implemented in the current version
|
||||||
|
pub community_max_vote_weight_addin: Option<Pubkey>,
|
||||||
|
|
||||||
/// Reserved for council voter weight addin
|
/// Addin providing voter weights for council token
|
||||||
pub reserved_2: Option<Pubkey>,
|
/// Note: This field is not implemented in the current version
|
||||||
|
pub council_voter_weight_addin: Option<Pubkey>,
|
||||||
|
|
||||||
/// Reserved for council max vote weight addin
|
/// Addin providing max vote weight for council token
|
||||||
pub reserved_3: Option<Pubkey>,
|
/// Note: This field is not implemented in the current version
|
||||||
|
pub council_max_vote_weight_addin: Option<Pubkey>,
|
||||||
|
|
||||||
/// Reserved
|
/// Reserved
|
||||||
pub reserved: [u8; 128],
|
pub reserved: [u8; 128],
|
||||||
|
@ -56,7 +56,7 @@ pub fn get_realm_config_data(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
realm_config_info: &AccountInfo,
|
realm_config_info: &AccountInfo,
|
||||||
) -> Result<RealmConfigAccount, ProgramError> {
|
) -> Result<RealmConfigAccount, ProgramError> {
|
||||||
get_account_data::<RealmConfigAccount>(realm_config_info, program_id)
|
get_account_data::<RealmConfigAccount>(program_id, realm_config_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes RealmConfig account and checks the owner program and the Realm it belongs to
|
/// Deserializes RealmConfig account and checks the owner program and the Realm it belongs to
|
||||||
|
@ -95,9 +95,9 @@ mod test {
|
||||||
account_type: GovernanceAccountType::Realm,
|
account_type: GovernanceAccountType::Realm,
|
||||||
realm: Pubkey::new_unique(),
|
realm: Pubkey::new_unique(),
|
||||||
community_voter_weight_addin: Some(Pubkey::new_unique()),
|
community_voter_weight_addin: Some(Pubkey::new_unique()),
|
||||||
reserved_1: Some(Pubkey::new_unique()),
|
community_max_vote_weight_addin: Some(Pubkey::new_unique()),
|
||||||
reserved_2: Some(Pubkey::new_unique()),
|
council_voter_weight_addin: Some(Pubkey::new_unique()),
|
||||||
reserved_3: Some(Pubkey::new_unique()),
|
council_max_vote_weight_addin: Some(Pubkey::new_unique()),
|
||||||
reserved: [0; 128],
|
reserved: [0; 128],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,12 +5,9 @@ use solana_program::{
|
||||||
account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized,
|
account_info::AccountInfo, program_error::ProgramError, program_pack::IsInitialized,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::{get_account_data, AccountMaxSize};
|
||||||
|
|
||||||
use crate::{
|
use crate::{error::GovernanceError, PROGRAM_AUTHORITY_SEED};
|
||||||
error::GovernanceError,
|
|
||||||
tools::account::{get_account_data, AccountMaxSize},
|
|
||||||
PROGRAM_AUTHORITY_SEED,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::state::enums::GovernanceAccountType;
|
use crate::state::enums::GovernanceAccountType;
|
||||||
|
|
||||||
|
@ -93,7 +90,7 @@ pub fn get_signatory_record_data(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
signatory_record_info: &AccountInfo,
|
signatory_record_info: &AccountInfo,
|
||||||
) -> Result<SignatoryRecord, ProgramError> {
|
) -> Result<SignatoryRecord, ProgramError> {
|
||||||
get_account_data::<SignatoryRecord>(signatory_record_info, program_id)
|
get_account_data::<SignatoryRecord>(program_id, signatory_record_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes SignatoryRecord and validates its PDA
|
/// Deserializes SignatoryRecord and validates its PDA
|
||||||
|
|
|
@ -9,7 +9,6 @@ use crate::{
|
||||||
enums::GovernanceAccountType, governance::GovernanceConfig, realm::Realm,
|
enums::GovernanceAccountType, governance::GovernanceConfig, realm::Realm,
|
||||||
realm_config::get_realm_config_data_for_realm,
|
realm_config::get_realm_config_data_for_realm,
|
||||||
},
|
},
|
||||||
tools::account::{get_account_data, AccountMaxSize},
|
|
||||||
PROGRAM_AUTHORITY_SEED,
|
PROGRAM_AUTHORITY_SEED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -20,6 +19,7 @@ use solana_program::{
|
||||||
program_pack::IsInitialized,
|
program_pack::IsInitialized,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::{get_account_data, AccountMaxSize};
|
||||||
|
|
||||||
/// Governance Token Owner Record
|
/// Governance Token Owner Record
|
||||||
/// Account PDA seeds: ['governance', realm, token_mint, token_owner ]
|
/// Account PDA seeds: ['governance', realm, token_mint, token_owner ]
|
||||||
|
@ -241,7 +241,7 @@ pub fn get_token_owner_record_data(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
token_owner_record_info: &AccountInfo,
|
token_owner_record_info: &AccountInfo,
|
||||||
) -> Result<TokenOwnerRecord, ProgramError> {
|
) -> Result<TokenOwnerRecord, ProgramError> {
|
||||||
get_account_data::<TokenOwnerRecord>(token_owner_record_info, program_id)
|
get_account_data::<TokenOwnerRecord>(program_id, token_owner_record_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes TokenOwnerRecord account and checks its PDA against the provided seeds
|
/// Deserializes TokenOwnerRecord account and checks its PDA against the provided seeds
|
||||||
|
|
|
@ -4,10 +4,11 @@ use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
|
||||||
use solana_program::account_info::AccountInfo;
|
use solana_program::account_info::AccountInfo;
|
||||||
use solana_program::program_error::ProgramError;
|
use solana_program::program_error::ProgramError;
|
||||||
use solana_program::{program_pack::IsInitialized, pubkey::Pubkey};
|
use solana_program::{program_pack::IsInitialized, pubkey::Pubkey};
|
||||||
|
use spl_governance_tools::account::{get_account_data, AccountMaxSize};
|
||||||
|
|
||||||
use crate::error::GovernanceError;
|
use crate::error::GovernanceError;
|
||||||
use crate::tools::account::get_account_data;
|
|
||||||
use crate::{tools::account::AccountMaxSize, PROGRAM_AUTHORITY_SEED};
|
use crate::PROGRAM_AUTHORITY_SEED;
|
||||||
|
|
||||||
use crate::state::enums::{GovernanceAccountType, VoteWeight};
|
use crate::state::enums::{GovernanceAccountType, VoteWeight};
|
||||||
|
|
||||||
|
@ -55,7 +56,7 @@ pub fn get_vote_record_data(
|
||||||
program_id: &Pubkey,
|
program_id: &Pubkey,
|
||||||
vote_record_info: &AccountInfo,
|
vote_record_info: &AccountInfo,
|
||||||
) -> Result<VoteRecord, ProgramError> {
|
) -> Result<VoteRecord, ProgramError> {
|
||||||
get_account_data::<VoteRecord>(vote_record_info, program_id)
|
get_account_data::<VoteRecord>(program_id, vote_record_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserializes VoteRecord and checks it belongs to the provided Proposal and Governing Token Owner
|
/// Deserializes VoteRecord and checks it belongs to the provided Proposal and Governing Token Owner
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
//! Utility functions
|
//! Utility functions
|
||||||
|
|
||||||
pub mod account;
|
|
||||||
|
|
||||||
pub mod spl_token;
|
pub mod spl_token;
|
||||||
|
|
||||||
pub mod bpf_loader_upgradeable;
|
pub mod bpf_loader_upgradeable;
|
||||||
|
|
Binary file not shown.
|
@ -5,6 +5,7 @@ use solana_program_test::*;
|
||||||
|
|
||||||
use program_test::*;
|
use program_test::*;
|
||||||
use spl_governance::{error::GovernanceError, state::enums::VoteThresholdPercentage};
|
use spl_governance::{error::GovernanceError, state::enums::VoteThresholdPercentage};
|
||||||
|
use spl_governance_tools::error::GovernanceToolsError;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_create_account_governance() {
|
async fn test_create_account_governance() {
|
||||||
|
@ -77,7 +78,7 @@ async fn test_create_account_governance_with_invalid_realm_error() {
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
||||||
assert_eq!(err, GovernanceError::InvalidAccountType.into());
|
assert_eq!(err, GovernanceToolsError::InvalidAccountType.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
|
@ -6,6 +6,7 @@ use solana_program_test::*;
|
||||||
use program_test::*;
|
use program_test::*;
|
||||||
use solana_sdk::{signature::Keypair, signer::Signer};
|
use solana_sdk::{signature::Keypair, signer::Signer};
|
||||||
use spl_governance::error::GovernanceError;
|
use spl_governance::error::GovernanceError;
|
||||||
|
use spl_governance_tools::error::GovernanceToolsError;
|
||||||
use spl_token::error::TokenError;
|
use spl_token::error::TokenError;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
@ -223,5 +224,5 @@ async fn test_create_mint_governance_with_invalid_realm_error() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assert_eq!(err, GovernanceError::InvalidAccountType.into());
|
assert_eq!(err, GovernanceToolsError::InvalidAccountType.into());
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use spl_governance::{
|
||||||
error::GovernanceError, tools::bpf_loader_upgradeable::get_program_upgrade_authority,
|
error::GovernanceError, tools::bpf_loader_upgradeable::get_program_upgrade_authority,
|
||||||
};
|
};
|
||||||
use spl_governance_test_sdk::tools::ProgramInstructionError;
|
use spl_governance_test_sdk::tools::ProgramInstructionError;
|
||||||
|
use spl_governance_tools::error::GovernanceToolsError;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_create_program_governance() {
|
async fn test_create_program_governance() {
|
||||||
|
@ -232,5 +233,5 @@ async fn test_create_program_governance_with_invalid_realm_error() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assert_eq!(err, GovernanceError::InvalidAccountType.into());
|
assert_eq!(err, GovernanceToolsError::InvalidAccountType.into());
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ use solana_program_test::*;
|
||||||
use program_test::*;
|
use program_test::*;
|
||||||
use solana_sdk::{signature::Keypair, signer::Signer};
|
use solana_sdk::{signature::Keypair, signer::Signer};
|
||||||
use spl_governance::error::GovernanceError;
|
use spl_governance::error::GovernanceError;
|
||||||
|
use spl_governance_tools::error::GovernanceToolsError;
|
||||||
|
|
||||||
use spl_token::error::TokenError;
|
use spl_token::error::TokenError;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
@ -221,5 +223,5 @@ async fn test_create_token_governance_with_invalid_realm_error() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assert_eq!(err, GovernanceError::InvalidAccountType.into());
|
assert_eq!(err, GovernanceToolsError::InvalidAccountType.into());
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ use spl_governance::{
|
||||||
};
|
};
|
||||||
use spl_governance_test_sdk::tools::ProgramInstructionError;
|
use spl_governance_test_sdk::tools::ProgramInstructionError;
|
||||||
|
|
||||||
|
use spl_governance_tools::error::GovernanceToolsError;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_set_governance_config() {
|
async fn test_set_governance_config() {
|
||||||
// Arrange
|
// Arrange
|
||||||
|
@ -145,7 +147,7 @@ async fn test_set_governance_config_with_fake_governance_signer_error() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assert_eq!(err, GovernanceError::AccountDoesNotExist.into());
|
assert_eq!(err, GovernanceToolsError::AccountDoesNotExist.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use solana_program_test::find_file;
|
||||||
|
use std::{process::Command, sync::Mutex};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref VOTER_WEIGHT_ADDIN_BUILD_GUARD: Mutex::<u8> = Mutex::new(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ensure_voter_weight_addin_is_built() {
|
||||||
|
if find_file("spl_governance_voter_weight_addin.so").is_none() {
|
||||||
|
let _guard = VOTER_WEIGHT_ADDIN_BUILD_GUARD.lock().unwrap();
|
||||||
|
if find_file("spl_governance_voter_weight_addin.so").is_none() {
|
||||||
|
assert!(Command::new("cargo")
|
||||||
|
.args(&[
|
||||||
|
"build-bpf",
|
||||||
|
"--manifest-path",
|
||||||
|
"../voter-weight-addin/program/Cargo.toml",
|
||||||
|
])
|
||||||
|
.status()
|
||||||
|
.expect("Failed to build voter-weight-addin program")
|
||||||
|
.success());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -52,6 +52,7 @@ use spl_governance::{
|
||||||
tools::bpf_loader_upgradeable::get_program_data_address,
|
tools::bpf_loader_upgradeable::get_program_data_address,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod addins;
|
||||||
pub mod cookies;
|
pub mod cookies;
|
||||||
|
|
||||||
use crate::program_test::cookies::{
|
use crate::program_test::cookies::{
|
||||||
|
@ -63,10 +64,13 @@ use spl_governance_test_sdk::{
|
||||||
ProgramTestBench, TestBenchProgram,
|
ProgramTestBench, TestBenchProgram,
|
||||||
};
|
};
|
||||||
|
|
||||||
use self::cookies::{
|
use self::{
|
||||||
|
addins::ensure_voter_weight_addin_is_built,
|
||||||
|
cookies::{
|
||||||
GovernanceCookie, GovernedAccountCookie, GovernedMintCookie, GovernedProgramCookie,
|
GovernanceCookie, GovernedAccountCookie, GovernedMintCookie, GovernedProgramCookie,
|
||||||
GovernedTokenCookie, ProposalCookie, ProposalInstructionCookie, RealmCookie,
|
GovernedTokenCookie, ProposalCookie, ProposalInstructionCookie, RealmCookie,
|
||||||
TokenOwnerRecordCookie, VoteRecordCookie,
|
TokenOwnerRecordCookie, VoteRecordCookie,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct GovernanceProgramTest {
|
pub struct GovernanceProgramTest {
|
||||||
|
@ -84,6 +88,8 @@ impl GovernanceProgramTest {
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub async fn start_with_voter_weight_addin() -> Self {
|
pub async fn start_with_voter_weight_addin() -> Self {
|
||||||
|
ensure_voter_weight_addin_is_built();
|
||||||
|
|
||||||
Self::start_impl(true).await
|
Self::start_impl(true).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,9 +257,9 @@ impl GovernanceProgramTest {
|
||||||
account_type: GovernanceAccountType::RealmConfig,
|
account_type: GovernanceAccountType::RealmConfig,
|
||||||
realm: realm_address,
|
realm: realm_address,
|
||||||
community_voter_weight_addin: self.voter_weight_addin_id,
|
community_voter_weight_addin: self.voter_weight_addin_id,
|
||||||
reserved_1: None,
|
community_max_vote_weight_addin: None,
|
||||||
reserved_2: None,
|
council_voter_weight_addin: None,
|
||||||
reserved_3: None,
|
council_max_vote_weight_addin: None,
|
||||||
reserved: [0; 128],
|
reserved: [0; 128],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -815,9 +821,9 @@ impl GovernanceProgramTest {
|
||||||
community_voter_weight_addin: Some(
|
community_voter_weight_addin: Some(
|
||||||
set_realm_config_ix.accounts[community_voter_weight_addin_index].pubkey,
|
set_realm_config_ix.accounts[community_voter_weight_addin_index].pubkey,
|
||||||
),
|
),
|
||||||
reserved_1: None,
|
community_max_vote_weight_addin: None,
|
||||||
reserved_2: None,
|
council_voter_weight_addin: None,
|
||||||
reserved_3: None,
|
council_max_vote_weight_addin: None,
|
||||||
reserved: [0; 128],
|
reserved: [0; 128],
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -2194,8 +2200,6 @@ impl GovernanceProgramTest {
|
||||||
|
|
||||||
// Governance program has no dependency on the voter-weight-addin program and hence we can't use its instruction creator here
|
// Governance program has no dependency on the voter-weight-addin program and hence we can't use its instruction creator here
|
||||||
// and the instruction has to be created manually
|
// and the instruction has to be created manually
|
||||||
// TODO: Currently the addin spl_governance_voter_weight_addin.so must be manually copied to tests/fixtures to work on CI
|
|
||||||
// We should automate this step as part of the build to build the addin before governance
|
|
||||||
let accounts = vec![
|
let accounts = vec![
|
||||||
AccountMeta::new_readonly(self.program_id, false),
|
AccountMeta::new_readonly(self.program_id, false),
|
||||||
AccountMeta::new_readonly(token_owner_record_cookie.account.realm, false),
|
AccountMeta::new_readonly(token_owner_record_cookie.account.realm, false),
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Governance Test SDK
|
||||||
|
|
||||||
|
Governance test SDK is a set of test utility functions used across the governance programs ecosystem
|
|
@ -0,0 +1,20 @@
|
||||||
|
[package]
|
||||||
|
name = "spl-governance-tools"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "Solana Program Library Governance Tools"
|
||||||
|
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||||
|
repository = "https://github.com/solana-labs/solana-program-library"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
arrayref = "0.3.6"
|
||||||
|
bincode = "1.3.2"
|
||||||
|
borsh = "0.9.1"
|
||||||
|
num-derive = "0.3"
|
||||||
|
num-traits = "0.2"
|
||||||
|
serde = "1.0.127"
|
||||||
|
serde_derive = "1.0.103"
|
||||||
|
solana-program = "1.8.0"
|
||||||
|
spl-token = { version = "3.2", path = "../../token/program", features = [ "no-entrypoint" ] }
|
||||||
|
thiserror = "1.0"
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Governance Tool
|
||||||
|
|
||||||
|
Governance tools is a set of general purpose utility functions used across the governance programs ecosystem
|
|
@ -2,12 +2,12 @@
|
||||||
|
|
||||||
use borsh::{BorshDeserialize, BorshSerialize};
|
use borsh::{BorshDeserialize, BorshSerialize};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, borsh::try_from_slice_unchecked, msg, program::invoke_signed,
|
account_info::AccountInfo, borsh::try_from_slice_unchecked, msg, program::invoke,
|
||||||
program_error::ProgramError, program_pack::IsInitialized, pubkey::Pubkey, rent::Rent,
|
program::invoke_signed, program_error::ProgramError, program_pack::IsInitialized,
|
||||||
system_instruction::create_account,
|
pubkey::Pubkey, rent::Rent, system_instruction::create_account, system_program, sysvar::Sysvar,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::error::GovernanceError;
|
use crate::error::GovernanceToolsError;
|
||||||
|
|
||||||
/// Trait for accounts to return their max size
|
/// Trait for accounts to return their max size
|
||||||
pub trait AccountMaxSize {
|
pub trait AccountMaxSize {
|
||||||
|
@ -17,6 +17,58 @@ pub trait AccountMaxSize {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a new account and serializes data into it using AccountMaxSize to determine the account's size
|
||||||
|
pub fn create_and_serialize_account<'a, T: BorshSerialize + AccountMaxSize>(
|
||||||
|
payer_info: &AccountInfo<'a>,
|
||||||
|
account_info: &AccountInfo<'a>,
|
||||||
|
account_data: &T,
|
||||||
|
program_id: &Pubkey,
|
||||||
|
system_info: &AccountInfo<'a>,
|
||||||
|
) -> Result<(), ProgramError> {
|
||||||
|
// Assert the account is not initialized yet
|
||||||
|
if !(account_info.data_is_empty() && *account_info.owner == system_program::id()) {
|
||||||
|
return Err(GovernanceToolsError::AccountAlreadyInitialized.into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let (serialized_data, account_size) = if let Some(max_size) = account_data.get_max_size() {
|
||||||
|
(None, max_size)
|
||||||
|
} else {
|
||||||
|
let serialized_data = account_data.try_to_vec()?;
|
||||||
|
let account_size = serialized_data.len();
|
||||||
|
(Some(serialized_data), account_size)
|
||||||
|
};
|
||||||
|
|
||||||
|
let rent = Rent::get()?;
|
||||||
|
|
||||||
|
let create_account_instruction = create_account(
|
||||||
|
payer_info.key,
|
||||||
|
account_info.key,
|
||||||
|
rent.minimum_balance(account_size),
|
||||||
|
account_size as u64,
|
||||||
|
program_id,
|
||||||
|
);
|
||||||
|
|
||||||
|
invoke(
|
||||||
|
&create_account_instruction,
|
||||||
|
&[
|
||||||
|
payer_info.clone(),
|
||||||
|
account_info.clone(),
|
||||||
|
system_info.clone(),
|
||||||
|
],
|
||||||
|
)?;
|
||||||
|
|
||||||
|
if let Some(serialized_data) = serialized_data {
|
||||||
|
account_info
|
||||||
|
.data
|
||||||
|
.borrow_mut()
|
||||||
|
.copy_from_slice(&serialized_data);
|
||||||
|
} else {
|
||||||
|
account_data.serialize(&mut *account_info.data.borrow_mut())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new account and serializes data into it using the provided seeds to invoke signed CPI call
|
/// Creates a new account and serializes data into it using the provided seeds to invoke signed CPI call
|
||||||
/// Note: This functions also checks the provided account PDA matches the supplied seeds
|
/// Note: This functions also checks the provided account PDA matches the supplied seeds
|
||||||
pub fn create_and_serialize_account_signed<'a, T: BorshSerialize + AccountMaxSize>(
|
pub fn create_and_serialize_account_signed<'a, T: BorshSerialize + AccountMaxSize>(
|
||||||
|
@ -85,14 +137,14 @@ pub fn create_and_serialize_account_signed<'a, T: BorshSerialize + AccountMaxSiz
|
||||||
|
|
||||||
/// Deserializes account and checks it's initialized and owned by the specified program
|
/// Deserializes account and checks it's initialized and owned by the specified program
|
||||||
pub fn get_account_data<T: BorshDeserialize + IsInitialized>(
|
pub fn get_account_data<T: BorshDeserialize + IsInitialized>(
|
||||||
account_info: &AccountInfo,
|
|
||||||
owner_program_id: &Pubkey,
|
owner_program_id: &Pubkey,
|
||||||
|
account_info: &AccountInfo,
|
||||||
) -> Result<T, ProgramError> {
|
) -> Result<T, ProgramError> {
|
||||||
if account_info.data_is_empty() {
|
if account_info.data_is_empty() {
|
||||||
return Err(GovernanceError::AccountDoesNotExist.into());
|
return Err(GovernanceToolsError::AccountDoesNotExist.into());
|
||||||
}
|
}
|
||||||
if account_info.owner != owner_program_id {
|
if account_info.owner != owner_program_id {
|
||||||
return Err(GovernanceError::InvalidAccountOwner.into());
|
return Err(GovernanceToolsError::InvalidAccountOwner.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let account: T = try_from_slice_unchecked(&account_info.data.borrow())?;
|
let account: T = try_from_slice_unchecked(&account_info.data.borrow())?;
|
||||||
|
@ -111,17 +163,17 @@ pub fn assert_is_valid_account<T: BorshDeserialize + PartialEq>(
|
||||||
owner_program_id: &Pubkey,
|
owner_program_id: &Pubkey,
|
||||||
) -> Result<(), ProgramError> {
|
) -> Result<(), ProgramError> {
|
||||||
if account_info.owner != owner_program_id {
|
if account_info.owner != owner_program_id {
|
||||||
return Err(GovernanceError::InvalidAccountOwner.into());
|
return Err(GovernanceToolsError::InvalidAccountOwner.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if account_info.data_is_empty() {
|
if account_info.data_is_empty() {
|
||||||
return Err(GovernanceError::AccountDoesNotExist.into());
|
return Err(GovernanceToolsError::AccountDoesNotExist.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let account_type: T = try_from_slice_unchecked(&account_info.data.borrow())?;
|
let account_type: T = try_from_slice_unchecked(&account_info.data.borrow())?;
|
||||||
|
|
||||||
if account_type != expected_account_type {
|
if account_type != expected_account_type {
|
||||||
return Err(GovernanceError::InvalidAccountType.into());
|
return Err(GovernanceToolsError::InvalidAccountType.into());
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
|
@ -0,0 +1,47 @@
|
||||||
|
//! Error types
|
||||||
|
|
||||||
|
use num_derive::FromPrimitive;
|
||||||
|
use solana_program::{
|
||||||
|
decode_error::DecodeError,
|
||||||
|
msg,
|
||||||
|
program_error::{PrintProgramError, ProgramError},
|
||||||
|
};
|
||||||
|
use thiserror::Error;
|
||||||
|
|
||||||
|
/// Errors that may be returned by the GovernanceTools
|
||||||
|
#[derive(Clone, Debug, Eq, Error, FromPrimitive, PartialEq)]
|
||||||
|
pub enum GovernanceToolsError {
|
||||||
|
/// Account already initialized
|
||||||
|
#[error("Account already initialized")]
|
||||||
|
AccountAlreadyInitialized = 1100,
|
||||||
|
|
||||||
|
/// Account doesn't exist
|
||||||
|
#[error("Account doesn't exist")]
|
||||||
|
AccountDoesNotExist,
|
||||||
|
|
||||||
|
/// Invalid account owner
|
||||||
|
#[error("Invalid account owner")]
|
||||||
|
InvalidAccountOwner,
|
||||||
|
|
||||||
|
/// Invalid Account type
|
||||||
|
#[error("Invalid Account type")]
|
||||||
|
InvalidAccountType,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrintProgramError for GovernanceToolsError {
|
||||||
|
fn print<E>(&self) {
|
||||||
|
msg!("GOVERNANCE-TOOLS-ERROR: {}", &self.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<GovernanceToolsError> for ProgramError {
|
||||||
|
fn from(e: GovernanceToolsError) -> Self {
|
||||||
|
ProgramError::Custom(e as u32)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> DecodeError<T> for GovernanceToolsError {
|
||||||
|
fn type_of() -> &'static str {
|
||||||
|
"Governance Tools Error"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
pub mod account;
|
||||||
|
pub mod error;
|
|
@ -21,8 +21,8 @@ serde = "1.0.127"
|
||||||
serde_derive = "1.0.103"
|
serde_derive = "1.0.103"
|
||||||
solana-program = "1.7.11"
|
solana-program = "1.7.11"
|
||||||
spl-token = { version = "3.2", path = "../../../token/program", features = [ "no-entrypoint" ] }
|
spl-token = { version = "3.2", path = "../../../token/program", features = [ "no-entrypoint" ] }
|
||||||
spl-governance= { version = "2.1.1", path ="../../program", features = [ "no-entrypoint" ]}
|
spl-governance= { version = "2.1.2", path ="../../program", features = [ "no-entrypoint" ]}
|
||||||
spl-governance-chat= { version = "0.1.0", path ="../../chat/program", features = [ "no-entrypoint" ]}
|
spl-governance-tools= { version = "0.1.0", path ="../../tools"}
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,6 @@ use spl_governance::{
|
||||||
addins::voter_weight::{VoterWeightAccountType, VoterWeightRecord},
|
addins::voter_weight::{VoterWeightAccountType, VoterWeightRecord},
|
||||||
state::token_owner_record::get_token_owner_record_data_for_realm_and_governing_mint,
|
state::token_owner_record::get_token_owner_record_data_for_realm_and_governing_mint,
|
||||||
};
|
};
|
||||||
// TODO: Move to shared governance tools
|
|
||||||
use spl_governance_chat::tools::account::create_and_serialize_account;
|
|
||||||
|
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::{next_account_info, AccountInfo},
|
account_info::{next_account_info, AccountInfo},
|
||||||
|
@ -15,6 +13,7 @@ use solana_program::{
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
use spl_governance_tools::account::create_and_serialize_account;
|
||||||
|
|
||||||
use crate::instruction::VoterWeightAddinInstruction;
|
use crate::instruction::VoterWeightAddinInstruction;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue