Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions p-token/tests/initialize_immutable_owner.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
mod setup;

use {
setup::TOKEN_PROGRAM_ID,
solana_keypair::Keypair,
solana_program_pack::Pack,
solana_program_test::{tokio, ProgramTest},
solana_signer::Signer,
solana_system_interface::instruction::create_account,
solana_transaction::Transaction,
spl_token::state::AccountState,
};

#[tokio::test]
async fn initialize_immutable_owner() {
let context = ProgramTest::new("pinocchio_token_program", TOKEN_PROGRAM_ID, None)
.start_with_context()
.await;

// Given an uninitialize account.

let account = Keypair::new();

let account_size = 165;
let rent = context.banks_client.get_rent().await.unwrap();

// When we execute the initialize_immutable_owner instruction.

let instructions = vec![
create_account(
&context.payer.pubkey(),
&account.pubkey(),
rent.minimum_balance(account_size),
account_size as u64,
&TOKEN_PROGRAM_ID,
),
spl_token::instruction::initialize_immutable_owner(&TOKEN_PROGRAM_ID, &account.pubkey())
.unwrap(),
];

let tx = Transaction::new_signed_with_payer(
&instructions,
Some(&context.payer.pubkey()),
&[&context.payer, &account],
context.last_blockhash,
);
context.banks_client.process_transaction(tx).await.unwrap();

// Then the instruction should succeed.

let account = context
.banks_client
.get_account(account.pubkey())
.await
.unwrap();

assert!(account.is_some());

let account = account.unwrap();
let account = spl_token::state::Account::unpack_unchecked(&account.data).unwrap();

assert_eq!(account.state, AccountState::Uninitialized);
}
93 changes: 93 additions & 0 deletions p-token/tests/sync_native.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
mod setup;

use {
crate::setup::TOKEN_PROGRAM_ID,
mollusk_svm::{result::Check, Mollusk},
pinocchio_token_interface::{
native_mint,
state::{
account::Account as TokenAccount, account_state::AccountState, load_mut_unchecked,
},
},
solana_account::Account,
solana_program_pack::Pack,
solana_program_test::tokio,
solana_pubkey::Pubkey,
solana_rent::Rent,
solana_sdk_ids::bpf_loader_upgradeable,
};

fn create_token_account(
mint: &Pubkey,
owner: &Pubkey,
is_native: bool,
amount: u64,
program_owner: &Pubkey,
) -> Account {
let space = size_of::<TokenAccount>();
let mut lamports = Rent::default().minimum_balance(space);

let mut data: Vec<u8> = vec![0u8; space];
let token = unsafe { load_mut_unchecked::<TokenAccount>(data.as_mut_slice()).unwrap() };
token.set_account_state(AccountState::Initialized);
token.mint = *mint.as_array();
token.owner = *owner.as_array();
token.set_amount(amount);
token.set_native(is_native);

if is_native {
token.set_native_amount(lamports);
lamports = lamports.saturating_add(amount);
}

Account {
lamports,
data,
owner: *program_owner,
executable: false,
..Default::default()
}
}

/// Creates a Mollusk instance with the default feature set, excluding the
/// `bpf_account_data_direct_mapping` feature.
fn mollusk() -> Mollusk {
let mut mollusk = Mollusk::default();
mollusk.add_program(
&TOKEN_PROGRAM_ID,
"pinocchio_token_program",
&bpf_loader_upgradeable::id(),
);
mollusk
}

#[tokio::test]
async fn sync_native() {
let native_mint = Pubkey::new_from_array(native_mint::ID);
let authority_key = Pubkey::new_unique();

// native account
// - amount: 1_000_000_000
// - lamports: 2_000_000_000
let source_account_key = Pubkey::new_unique();
let mut source_account =
create_token_account(&native_mint, &authority_key, true, 0, &TOKEN_PROGRAM_ID);
source_account.lamports += 2_000_000_000;

let instruction =
spl_token::instruction::sync_native(&TOKEN_PROGRAM_ID, &source_account_key).unwrap();

// Executes the sync_native instruction.

let result = mollusk().process_and_validate_instruction_chain(
&[(&instruction, &[Check::success()])],
&[(source_account_key, source_account)],
);

result.resulting_accounts.iter().for_each(|(key, account)| {
if *key == source_account_key {
let token_account = spl_token::state::Account::unpack(&account.data).unwrap();
assert_eq!(token_account.amount, 2_000_000_000);
}
});
}