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

View File

@ -82,7 +82,11 @@ pub enum GovernanceInstruction {
/// 7. `[]` System /// 7. `[]` System
/// 8. `[]` SPL Token /// 8. `[]` SPL Token
/// 9. `[]` Sysvar Rent /// 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 /// 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 /// 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 /// Creates DepositGoverningTokens instruction
#[allow(clippy::too_many_arguments)]
pub fn deposit_governing_tokens( pub fn deposit_governing_tokens(
program_id: &Pubkey, program_id: &Pubkey,
// Accounts // Accounts
@ -518,6 +523,7 @@ pub fn deposit_governing_tokens(
governing_token_transfer_authority: &Pubkey, governing_token_transfer_authority: &Pubkey,
payer: &Pubkey, payer: &Pubkey,
// Args // Args
amount: u64,
governing_token_mint: &Pubkey, governing_token_mint: &Pubkey,
) -> Instruction { ) -> Instruction {
let token_owner_record_address = get_token_owner_record_address( 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), AccountMeta::new_readonly(sysvar::rent::id(), false),
]; ];
let instruction = GovernanceInstruction::DepositGoverningTokens {}; let instruction = GovernanceInstruction::DepositGoverningTokens { amount };
Instruction { Instruction {
program_id: *program_id, program_id: *program_id,

View File

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

View File

@ -21,9 +21,7 @@ use crate::{
}, },
tools::{ tools::{
account::create_and_serialize_account_signed, account::create_and_serialize_account_signed,
spl_token::{ spl_token::{get_spl_token_mint, get_spl_token_owner, transfer_spl_tokens},
get_spl_token_amount, get_spl_token_mint, get_spl_token_owner, transfer_spl_tokens,
},
}, },
}; };
@ -31,6 +29,7 @@ use crate::{
pub fn process_deposit_governing_tokens( pub fn process_deposit_governing_tokens(
program_id: &Pubkey, program_id: &Pubkey,
accounts: &[AccountInfo], accounts: &[AccountInfo],
amount: u64,
) -> ProgramResult { ) -> ProgramResult {
let account_info_iter = &mut accounts.iter(); let account_info_iter = &mut accounts.iter();
@ -59,8 +58,6 @@ pub fn process_deposit_governing_tokens(
governing_token_holding_info.key, governing_token_holding_info.key,
)?; )?;
let amount = get_spl_token_amount(governing_token_source_info)?;
transfer_spl_tokens( transfer_spl_tokens(
governing_token_source_info, governing_token_source_info,
governing_token_holding_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(()) 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 /// Computationally cheap method to get mint from a token account
/// It reads mint without deserializing full account data /// It reads mint without deserializing full account data
pub fn get_spl_token_mint(token_account_info: &AccountInfo) -> Result<Pubkey, ProgramError> { 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 transfer_authority = Keypair::new();
let token_source = Keypair::new(); let token_source = Keypair::new();
let amount = 10;
governance_test governance_test
.bench .bench
.create_token_account_with_transfer_authority( .create_token_account_with_transfer_authority(
&token_source, &token_source,
&realm_cookie.account.community_mint, &realm_cookie.account.community_mint,
&realm_cookie.community_mint_authority, &realm_cookie.community_mint_authority,
10, amount,
&token_owner, &token_owner,
&transfer_authority.pubkey(), &transfer_authority.pubkey(),
) )
@ -215,6 +217,7 @@ async fn test_deposit_initial_community_tokens_with_owner_must_sign_error() {
&token_owner.pubkey(), &token_owner.pubkey(),
&transfer_authority.pubkey(), &transfer_authority.pubkey(),
&governance_test.bench.context.payer.pubkey(), &governance_test.bench.context.payer.pubkey(),
amount,
&realm_cookie.account.community_mint, &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 invalid_owner = Keypair::new();
let amount = 10;
governance_test governance_test
.bench .bench
.create_token_account_with_transfer_authority( .create_token_account_with_transfer_authority(
&token_source, &token_source,
&realm_cookie.account.community_mint, &realm_cookie.account.community_mint,
&realm_cookie.community_mint_authority, &realm_cookie.community_mint_authority,
10, amount,
&token_owner, &token_owner,
&transfer_authority.pubkey(), &transfer_authority.pubkey(),
) )
@ -263,6 +268,7 @@ async fn test_deposit_initial_community_tokens_with_invalid_owner_error() {
&invalid_owner.pubkey(), &invalid_owner.pubkey(),
&transfer_authority.pubkey(), &transfer_authority.pubkey(),
&governance_test.bench.context.payer.pubkey(), &governance_test.bench.context.payer.pubkey(),
amount,
&realm_cookie.account.community_mint, &realm_cookie.account.community_mint,
); );
@ -290,13 +296,15 @@ async fn test_deposit_community_tokens_with_malicious_holding_account_error() {
.await .await
.unwrap(); .unwrap();
let amount = 50;
governance_test governance_test
.bench .bench
.mint_tokens( .mint_tokens(
&realm_cookie.account.community_mint, &realm_cookie.account.community_mint,
&realm_cookie.community_mint_authority, &realm_cookie.community_mint_authority,
&token_owner_record_cookie.token_source, &token_owner_record_cookie.token_source,
50, amount,
) )
.await; .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(),
&token_owner_record_cookie.token_owner.pubkey(), &token_owner_record_cookie.token_owner.pubkey(),
&governance_test.bench.context.payer.pubkey(), &governance_test.bench.context.payer.pubkey(),
amount,
&realm_cookie.account.community_mint, &realm_cookie.account.community_mint,
); );

View File

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