Skip to content
Open
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
26 changes: 13 additions & 13 deletions program/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ pub enum ProgramMetadataInstruction {
///
/// 0. `[w]` Buffer or metadata account.
/// 1. `[s]` Current authority account.
/// 2. `[o]` (optional) Program account.
/// 3. `[o]` (optional) Program data account.
/// 2. `[o]` Program account.
/// 3. `[o]` Program data account.
///
/// Instruction data:
///
Expand Down Expand Up @@ -111,9 +111,9 @@ pub enum ProgramMetadataInstruction {
///
/// 0. `[w]` Metadata account.
/// 1. `[s]` Authority account.
/// 2. `[o]` (optional) Buffer account to copy data from.
/// 3. `[o]` (optional) Program account.
/// 4. `[o]` (optional) Program data account.
/// 2. `[o]` Buffer account to copy data from.
/// 3. `[o]` Program account.
/// 4. `[o]` Program data account.
///
/// Instruction data:
///
Expand All @@ -136,8 +136,8 @@ pub enum ProgramMetadataInstruction {
///
/// 0. `[w]` Metadata account.
/// 1. `[s]` Authority account.
/// 2. `[o]` (optional) Program account.
/// 3. `[o]` (optional) Program data account.
/// 2. `[o]` Program account.
/// 3. `[o]` Program data account.
SetImmutable,

/// Resizes and withdraws excess lamports from a buffer or metadata account.
Expand All @@ -156,8 +156,8 @@ pub enum ProgramMetadataInstruction {
///
/// 0. `[w]` Buffer or metadata account.
/// 1. `[s]` Authority account.
/// 2. `[o]` (optional) Program account.
/// 3. `[o]` (optional) Program data account.
/// 2. `[o]` Program account.
/// 3. `[o]` Program data account.
/// 5. `[w]` Destination account.
/// 6. `[]` Rent sysvar account.
Trim,
Expand All @@ -180,8 +180,8 @@ pub enum ProgramMetadataInstruction {
///
/// 0. `[w]` Account to close.
/// 1. `[s]` Metadata authority or buffer account.
/// 2. `[o]` (optional) Program account.
/// 3. `[o]` (optional) Program data account.
/// 2. `[o]` Program account.
/// 3. `[o]` Program data account.
/// 5. `[w]` Destination account.
Close,

Expand Down Expand Up @@ -233,8 +233,8 @@ pub enum ProgramMetadataInstruction {
///
/// 0. `[w]` Buffer or metadata account.
/// 1. `[s]` Authority account.
/// 2. `[o]` (optional) Program account.
/// 3. `[o]` (optional) Program data account.
/// 2. `[o]` Program account.
/// 3. `[o]` Program data account.
///
/// Instruction data:
///
Expand Down
5 changes: 4 additions & 1 deletion program/src/processor/set_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ pub fn set_data(accounts: &mut [AccountView], instruction_data: &[u8]) -> Progra

// Update header and data (if needed).

if let Some(data) = update_header(metadata, args, data)? {
if let Some(data) = update_header(metadata, args, data).map_err(|err| match err {
ProgramError::InvalidAccountData => ProgramError::InvalidInstructionData,
_ => err,
})? {
// Realloc the metadata account if necessary.

// SAFETY: There are no other active borrows to the `metadata` account data.
Expand Down
136 changes: 135 additions & 1 deletion program/tests/allocate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use solana_account::Account;
use solana_program_error::ProgramError;
use solana_pubkey::Pubkey;
use solana_sdk_ids::system_program;
use spl_program_metadata::state::{buffer::Buffer, SEED_LEN};
use spl_program_metadata::{
error::ProgramMetadataError,
state::{buffer::Buffer, SEED_LEN},
};

#[test]
fn test_allocate_canonical() {
Expand Down Expand Up @@ -420,3 +423,134 @@ fn test_allocate_with_unfunded_account() {
],
);
}

#[test]
fn fail_allocate_keypair_with_seed() {
let buffer_key = Pubkey::new_unique();
let buffer_account =
create_funded_account(minimum_balance_for(Buffer::LEN), system_program::ID);

let mut seed = [0u8; SEED_LEN];
seed[0..3].copy_from_slice("idl".as_bytes());

process_instruction(
(
&allocate(&buffer_key, &buffer_key, None, None, Some(&seed)).unwrap(),
&[Check::err(ProgramError::InvalidInstructionData)],
),
&[
(buffer_key, buffer_account),
(PROGRAM_ID, Account::default()),
keyed_account_for_system_program(),
],
);
}

#[test]
fn fail_allocate_pda_with_wrong_seed() {
let authority_key = Pubkey::new_unique();

let program_data_key = Pubkey::new_unique();
let program_data_account = setup_program_data_account(Some(&authority_key));

let program_key = Pubkey::new_unique();
let program_account = setup_program_account(&program_data_key);

let mut seed = [0u8; SEED_LEN];
seed[0..3].copy_from_slice("idl".as_bytes());

let mut wrong_seed = [0u8; SEED_LEN];
wrong_seed[0..5].copy_from_slice("other".as_bytes());

let (buffer_key, _) = Pubkey::find_program_address(&[program_key.as_ref(), &seed], &PROGRAM_ID);
let buffer_account = create_empty_account(Buffer::LEN, PROGRAM_ID);

process_instruction(
(
&allocate(
&buffer_key,
&authority_key,
Some(&program_key),
Some(&program_data_key),
Some(&wrong_seed),
)
.unwrap(),
&[Check::err(ProgramError::InvalidSeeds)],
),
&[
(buffer_key, buffer_account),
(authority_key, Account::default()),
(program_key, program_account),
(program_data_key, program_data_account),
keyed_account_for_system_program(),
],
);
}

#[test]
fn fail_allocate_pda_for_non_executable_program() {
let authority_key = Pubkey::new_unique();

let program_data_key = Pubkey::new_unique();
let program_data_account = setup_program_data_account(Some(&authority_key));

let program_key = Pubkey::new_unique();
let program_account = Account::default();

let mut seed = [0u8; SEED_LEN];
seed[0..3].copy_from_slice("idl".as_bytes());

let (buffer_key, _) = Pubkey::find_program_address(
&[program_key.as_ref(), authority_key.as_ref(), &seed],
&PROGRAM_ID,
);
let buffer_account = create_empty_account(Buffer::LEN, PROGRAM_ID);

process_instruction(
(
&allocate(
&buffer_key,
&authority_key,
Some(&program_key),
Some(&program_data_key),
Some(&seed),
)
.unwrap(),
&[Check::err(ProgramError::Custom(
ProgramMetadataError::NotExecutableAccount as u32,
))],
),
&[
(buffer_key, buffer_account),
(authority_key, Account::default()),
(program_key, program_account),
(program_data_key, program_data_account),
keyed_account_for_system_program(),
],
);
}

#[test]
fn fail_allocate_already_initialized_buffer() {
let buffer_key = Pubkey::new_unique();
let buffer_account =
create_funded_account(minimum_balance_for(Buffer::LEN), system_program::ID);

process_instructions(
&[
(
&allocate(&buffer_key, &buffer_key, None, None, None).unwrap(),
&[Check::success()],
),
(
&allocate(&buffer_key, &buffer_key, None, None, None).unwrap(),
&[Check::err(ProgramError::AccountAlreadyInitialized)],
),
],
&[
(buffer_key, buffer_account),
(PROGRAM_ID, Account::default()),
keyed_account_for_system_program(),
],
);
}
Loading
Loading