use {
crate::{error::GovernanceError, state::token_owner_record::TokenOwnerRecordV2},
solana_program::{
account_info::AccountInfo, clock::Clock, program_error::ProgramError, pubkey::Pubkey,
sysvar::Sysvar,
},
spl_governance_addin_api::voter_weight::{VoterWeightAction, VoterWeightRecord},
spl_governance_tools::account::get_account_data,
};
pub fn assert_is_valid_voter_weight(
voter_weight_record: &VoterWeightRecord,
weight_action: VoterWeightAction,
weight_action_target: &Pubkey,
) -> Result<(), ProgramError> {
if let Some(voter_weight_expiry) = voter_weight_record.voter_weight_expiry {
let slot = Clock::get()?.slot;
if slot > voter_weight_expiry {
return Err(GovernanceError::VoterWeightRecordExpired.into());
}
}
if let Some(voter_weight_action) = &voter_weight_record.weight_action {
if voter_weight_action != &weight_action {
return Err(GovernanceError::VoterWeightRecordInvalidAction.into());
}
}
if let Some(voter_weight_action_target) = &voter_weight_record.weight_action_target {
if voter_weight_action_target != weight_action_target {
return Err(GovernanceError::VoterWeightRecordInvalidActionTarget.into());
}
}
Ok(())
}
pub fn get_voter_weight_record_data(
program_id: &Pubkey,
voter_weight_record_info: &AccountInfo,
) -> Result<VoterWeightRecord, ProgramError> {
get_account_data::<VoterWeightRecord>(program_id, voter_weight_record_info)
}
pub fn get_voter_weight_record_data_for_token_owner_record(
program_id: &Pubkey,
voter_weight_record_info: &AccountInfo,
token_owner_record: &TokenOwnerRecordV2,
) -> Result<VoterWeightRecord, ProgramError> {
let voter_weight_record_data =
get_voter_weight_record_data(program_id, voter_weight_record_info)?;
if voter_weight_record_data.realm != token_owner_record.realm {
return Err(GovernanceError::InvalidVoterWeightRecordForRealm.into());
}
if voter_weight_record_data.governing_token_mint != token_owner_record.governing_token_mint {
return Err(GovernanceError::InvalidVoterWeightRecordForGoverningTokenMint.into());
}
if voter_weight_record_data.governing_token_owner != token_owner_record.governing_token_owner {
return Err(GovernanceError::InvalidVoterWeightRecordForTokenOwner.into());
}
Ok(voter_weight_record_data)
}