Governance: Add deposit amount (#2485)

* feat: add amount to Deposit instruction

* feat: use try_from_slice_unchecked to support forward compatibility

* chore: make clippy happy

* chore: update comments
This commit is contained in:
Sebastian Bor 2021-10-13 19:59:30 +01:00 committed by GitHub
parent 5436ac239e
commit dc7f6be034
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 35 additions and 29 deletions

View File

@ -103,13 +103,14 @@ impl GovernanceChatProgramTest {
let token_source = Keypair::new();
let transfer_authority = Keypair::new();
let amount = 100;
self.bench
.create_token_account_with_transfer_authority(
&token_source,
&governing_token_mint_keypair.pubkey(),
&governing_token_mint_authority,
100,
amount,
&token_owner,
&transfer_authority.pubkey(),
)
@ -122,6 +123,7 @@ impl GovernanceChatProgramTest {
&token_owner.pubkey(),
&token_owner.pubkey(),
&self.bench.payer.pubkey(),
amount,
&governing_token_mint_keypair.pubkey(),
);
@ -244,6 +246,7 @@ impl GovernanceChatProgramTest {
&token_owner.pubkey(),
&token_owner.pubkey(),
&self.bench.payer.pubkey(),
deposit_amount,
&proposal_cookie.governing_token_mint,
);

View File

@ -82,7 +82,11 @@ pub enum GovernanceInstruction {
/// 7. `[]` System
/// 8. `[]` SPL Token
/// 9. `[]` Sysvar Rent
DepositGoverningTokens {},
DepositGoverningTokens {
/// The amount to deposit into the realm
#[allow(dead_code)]
amount: u64,
},
/// Withdraws governing tokens (Community or Council) from Governance Realm and downgrades your voter weight within the Realm
/// Note: It's only possible to withdraw tokens if the Voter doesn't have any outstanding active votes
@ -509,6 +513,7 @@ pub fn create_realm(
}
/// Creates DepositGoverningTokens instruction
#[allow(clippy::too_many_arguments)]
pub fn deposit_governing_tokens(
program_id: &Pubkey,
// Accounts
@ -518,6 +523,7 @@ pub fn deposit_governing_tokens(
governing_token_transfer_authority: &Pubkey,
payer: &Pubkey,
// Args
amount: u64,
governing_token_mint: &Pubkey,
) -> Instruction {
let token_owner_record_address = get_token_owner_record_address(
@ -543,7 +549,7 @@ pub fn deposit_governing_tokens(
AccountMeta::new_readonly(sysvar::rent::id(), false),
];
let instruction = GovernanceInstruction::DepositGoverningTokens {};
let instruction = GovernanceInstruction::DepositGoverningTokens { amount };
Instruction {
program_id: *program_id,

View File

@ -26,7 +26,6 @@ mod process_sign_off_proposal;
mod process_withdraw_governing_tokens;
use crate::instruction::GovernanceInstruction;
use borsh::BorshDeserialize;
use process_add_signatory::*;
use process_cancel_proposal::*;
@ -54,8 +53,8 @@ use process_sign_off_proposal::*;
use process_withdraw_governing_tokens::*;
use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, msg, program_error::ProgramError,
pubkey::Pubkey,
account_info::AccountInfo, borsh::try_from_slice_unchecked, entrypoint::ProgramResult, msg,
program_error::ProgramError, pubkey::Pubkey,
};
/// Processes an instruction
@ -64,8 +63,9 @@ pub fn process_instruction(
accounts: &[AccountInfo],
input: &[u8],
) -> ProgramResult {
let instruction = GovernanceInstruction::try_from_slice(input)
.map_err(|_| ProgramError::InvalidInstructionData)?;
// Use try_from_slice_unchecked to support forward compatibility of newer UI with older program
let instruction: GovernanceInstruction =
try_from_slice_unchecked(input).map_err(|_| ProgramError::InvalidInstructionData)?;
if let GovernanceInstruction::InsertInstruction {
index,
@ -88,8 +88,8 @@ pub fn process_instruction(
process_create_realm(program_id, accounts, name, config_args)
}
GovernanceInstruction::DepositGoverningTokens {} => {
process_deposit_governing_tokens(program_id, accounts)
GovernanceInstruction::DepositGoverningTokens { amount } => {
process_deposit_governing_tokens(program_id, accounts, amount)
}
GovernanceInstruction::WithdrawGoverningTokens {} => {

View File

@ -21,9 +21,7 @@ use crate::{
},
tools::{
account::create_and_serialize_account_signed,
spl_token::{
get_spl_token_amount, get_spl_token_mint, get_spl_token_owner, transfer_spl_tokens,
},
spl_token::{get_spl_token_mint, get_spl_token_owner, transfer_spl_tokens},
},
};
@ -31,6 +29,7 @@ use crate::{
pub fn process_deposit_governing_tokens(
program_id: &Pubkey,
accounts: &[AccountInfo],
amount: u64,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
@ -59,8 +58,6 @@ pub fn process_deposit_governing_tokens(
governing_token_holding_info.key,
)?;
let amount = get_spl_token_amount(governing_token_source_info)?;
transfer_spl_tokens(
governing_token_source_info,
governing_token_holding_info,

View File

@ -220,17 +220,6 @@ pub fn assert_is_valid_spl_token_mint(mint_info: &AccountInfo) -> Result<(), Pro
Ok(())
}
/// Computationally cheap method to get amount from a token account
/// It reads amount without deserializing full account data
pub fn get_spl_token_amount(token_account_info: &AccountInfo) -> Result<u64, ProgramError> {
assert_is_valid_spl_token_account(token_account_info)?;
// TokeAccount layout: mint(32), owner(32), amount(8), ...
let data = token_account_info.try_borrow_data()?;
let amount = array_ref![data, 64, 8];
Ok(u64::from_le_bytes(*amount))
}
/// Computationally cheap method to get mint from a token account
/// It reads mint without deserializing full account data
pub fn get_spl_token_mint(token_account_info: &AccountInfo) -> Result<Pubkey, ProgramError> {

View File

@ -196,13 +196,15 @@ async fn test_deposit_initial_community_tokens_with_owner_must_sign_error() {
let transfer_authority = Keypair::new();
let token_source = Keypair::new();
let amount = 10;
governance_test
.bench
.create_token_account_with_transfer_authority(
&token_source,
&realm_cookie.account.community_mint,
&realm_cookie.community_mint_authority,
10,
amount,
&token_owner,
&transfer_authority.pubkey(),
)
@ -215,6 +217,7 @@ async fn test_deposit_initial_community_tokens_with_owner_must_sign_error() {
&token_owner.pubkey(),
&transfer_authority.pubkey(),
&governance_test.bench.context.payer.pubkey(),
amount,
&realm_cookie.account.community_mint,
);
@ -244,13 +247,15 @@ async fn test_deposit_initial_community_tokens_with_invalid_owner_error() {
let invalid_owner = Keypair::new();
let amount = 10;
governance_test
.bench
.create_token_account_with_transfer_authority(
&token_source,
&realm_cookie.account.community_mint,
&realm_cookie.community_mint_authority,
10,
amount,
&token_owner,
&transfer_authority.pubkey(),
)
@ -263,6 +268,7 @@ async fn test_deposit_initial_community_tokens_with_invalid_owner_error() {
&invalid_owner.pubkey(),
&transfer_authority.pubkey(),
&governance_test.bench.context.payer.pubkey(),
amount,
&realm_cookie.account.community_mint,
);
@ -290,13 +296,15 @@ async fn test_deposit_community_tokens_with_malicious_holding_account_error() {
.await
.unwrap();
let amount = 50;
governance_test
.bench
.mint_tokens(
&realm_cookie.account.community_mint,
&realm_cookie.community_mint_authority,
&token_owner_record_cookie.token_source,
50,
amount,
)
.await;
@ -307,6 +315,7 @@ async fn test_deposit_community_tokens_with_malicious_holding_account_error() {
&token_owner_record_cookie.token_owner.pubkey(),
&token_owner_record_cookie.token_owner.pubkey(),
&governance_test.bench.context.payer.pubkey(),
amount,
&realm_cookie.account.community_mint,
);

View File

@ -523,6 +523,7 @@ impl GovernanceProgramTest {
&token_owner.pubkey(),
&token_owner.pubkey(),
&self.bench.payer.pubkey(),
amount,
governing_mint,
);
@ -615,6 +616,7 @@ impl GovernanceProgramTest {
&token_owner_record_cookie.token_owner.pubkey(),
&token_owner_record_cookie.token_owner.pubkey(),
&self.bench.payer.pubkey(),
amount,
governing_token_mint,
);