Skip to content

Commit

Permalink
return to group nomenclature
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Oct 18, 2023
1 parent 8ecd111 commit c46f300
Show file tree
Hide file tree
Showing 5 changed files with 200 additions and 216 deletions.
106 changes: 50 additions & 56 deletions token-group/example/src/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,21 @@ fn check_update_authority(
}

/// Processes an [InitializeGroup](enum.GroupInterfaceInstruction.html)
/// instruction for a `Collection`
pub fn process_initialize_collection(
/// instruction
pub fn process_initialize_group(
_program_id: &Pubkey,
accounts: &[AccountInfo],
data: InitializeGroup,
) -> ProgramResult {
// Assumes one has already created a mint for the collection.
// Assumes one has already created a mint for the group.
let account_info_iter = &mut accounts.iter();

// Accounts expected by this instruction:
//
// 0. `[w]` Collection (Group)
// 0. `[w]` Group
// 1. `[]` Mint
// 2. `[s]` Mint authority
let collection_info = next_account_info(account_info_iter)?;
let group_info = next_account_info(account_info_iter)?;
let mint_info = next_account_info(account_info_iter)?;
let mint_authority_info = next_account_info(account_info_iter)?;

Expand All @@ -71,18 +71,18 @@ pub fn process_initialize_collection(
}

// Allocate a TLV entry for the space and write it in
let mut buffer = collection_info.try_borrow_mut_data()?;
let mut buffer = group_info.try_borrow_mut_data()?;
let mut state = TlvStateMut::unpack(&mut buffer)?;
let (collection, _) = state.init_value::<TokenGroup>(false)?;
*collection = TokenGroup::new(data.update_authority, data.max_size.into());
let (group, _) = state.init_value::<TokenGroup>(false)?;
*group = TokenGroup::new(data.update_authority, data.max_size.into());

Ok(())
}

/// Processes an
/// [UpdateGroupMaxSize](enum.GroupInterfaceInstruction.html)
/// instruction for a `Collection`
pub fn process_update_collection_max_size(
/// instruction
pub fn process_update_group_max_size(
_program_id: &Pubkey,
accounts: &[AccountInfo],
data: UpdateGroupMaxSize,
Expand All @@ -91,27 +91,27 @@ pub fn process_update_collection_max_size(

// Accounts expected by this instruction:
//
// 0. `[w]` Collection (Group)
// 0. `[w]` Group
// 1. `[s]` Update authority
let collection_info = next_account_info(account_info_iter)?;
let group_info = next_account_info(account_info_iter)?;
let update_authority_info = next_account_info(account_info_iter)?;

let mut buffer = collection_info.try_borrow_mut_data()?;
let mut buffer = group_info.try_borrow_mut_data()?;
let mut state = TlvStateMut::unpack(&mut buffer)?;
let collection = state.get_first_value_mut::<TokenGroup>()?;
let group = state.get_first_value_mut::<TokenGroup>()?;

check_update_authority(update_authority_info, &collection.update_authority)?;
check_update_authority(update_authority_info, &group.update_authority)?;

// Update the max size (zero-copy)
collection.update_max_size(data.max_size.into())?;
group.update_max_size(data.max_size.into())?;

Ok(())
}

/// Processes an
/// [UpdateGroupAuthority](enum.GroupInterfaceInstruction.html)
/// instruction for a `Collection`
pub fn process_update_collection_authority(
/// instruction
pub fn process_update_group_authority(
_program_id: &Pubkey,
accounts: &[AccountInfo],
data: UpdateGroupAuthority,
Expand All @@ -120,49 +120,46 @@ pub fn process_update_collection_authority(

// Accounts expected by this instruction:
//
// 0. `[w]` Collection (Group)
// 0. `[w]` Group
// 1. `[s]` Current update authority
let collection_info = next_account_info(account_info_iter)?;
let group_info = next_account_info(account_info_iter)?;
let update_authority_info = next_account_info(account_info_iter)?;

let mut buffer = collection_info.try_borrow_mut_data()?;
let mut buffer = group_info.try_borrow_mut_data()?;
let mut state = TlvStateMut::unpack(&mut buffer)?;
let mut collection = state.get_first_value_mut::<TokenGroup>()?;
let mut group = state.get_first_value_mut::<TokenGroup>()?;

check_update_authority(update_authority_info, &collection.update_authority)?;
check_update_authority(update_authority_info, &group.update_authority)?;

// Update the authority (zero-copy)
collection.update_authority = data.new_authority;
group.update_authority = data.new_authority;

Ok(())
}

/// Processes an [InitializeMember](enum.GroupInterfaceInstruction.html)
/// instruction for a `Collection`
pub fn process_initialize_collection_member(
_program_id: &Pubkey,
accounts: &[AccountInfo],
) -> ProgramResult {
// For this group, we are going to assume the collection has been
/// instruction
pub fn process_initialize_member(_program_id: &Pubkey, accounts: &[AccountInfo]) -> ProgramResult {
// For this group, we are going to assume the group has been
// initialized, and we're also assuming a mint has been created for the
// member.
// Collection members in this example can have their own separate
// metadata that differs from the metadata of the collection, since
// Group members in this example can have their own separate
// metadata that differs from the metadata of the group, since
// metadata is not involved here.
let account_info_iter = &mut accounts.iter();

// Accounts expected by this instruction:
//
// 0. `[w]` Collection Member (Member)
// 1. `[]` Collection Member (Member) Mint
// 2. `[s]` Collection Member (Member) Mint authority
// 3. `[w]` Collection (Group)
// 4. `[s]` Collection (Group) update authority
// 0. `[w]` Member
// 1. `[]` Member Mint
// 2. `[s]` Member Mint authority
// 3. `[w]` Group
// 4. `[s]` Group update authority
let member_info = next_account_info(account_info_iter)?;
let member_mint_info = next_account_info(account_info_iter)?;
let member_mint_authority_info = next_account_info(account_info_iter)?;
let collection_info = next_account_info(account_info_iter)?;
let collection_update_authority_info = next_account_info(account_info_iter)?;
let group_info = next_account_info(account_info_iter)?;
let group_update_authority_info = next_account_info(account_info_iter)?;

// Mint checks on the member
{
Expand All @@ -181,22 +178,19 @@ pub fn process_initialize_collection_member(
}
}

// Increment the size of the collection
let mut buffer = collection_info.try_borrow_mut_data()?;
// Increment the size of the group
let mut buffer = group_info.try_borrow_mut_data()?;
let mut state = TlvStateMut::unpack(&mut buffer)?;
let collection = state.get_first_value_mut::<TokenGroup>()?;
let group = state.get_first_value_mut::<TokenGroup>()?;

check_update_authority(
collection_update_authority_info,
&collection.update_authority,
)?;
let member_number = collection.increment_size()?;
check_update_authority(group_update_authority_info, &group.update_authority)?;
let member_number = group.increment_size()?;

// Allocate a TLV entry for the space and write it in
let mut buffer = member_info.try_borrow_mut_data()?;
let mut state = TlvStateMut::unpack(&mut buffer)?;
let (member, _) = state.init_value::<TokenGroupMember>(false)?;
*member = TokenGroupMember::new(*collection_info.key, member_number);
*member = TokenGroupMember::new(*group_info.key, member_number);

Ok(())
}
Expand All @@ -206,20 +200,20 @@ pub fn process(program_id: &Pubkey, accounts: &[AccountInfo], input: &[u8]) -> P
let instruction = TokenGroupInstruction::unpack(input)?;
match instruction {
TokenGroupInstruction::InitializeGroup(data) => {
msg!("Instruction: InitializeCollection");
process_initialize_collection(program_id, accounts, data)
msg!("Instruction: InitializeGroup");
process_initialize_group(program_id, accounts, data)
}
TokenGroupInstruction::UpdateGroupMaxSize(data) => {
msg!("Instruction: UpdateCollectionMaxSize");
process_update_collection_max_size(program_id, accounts, data)
msg!("Instruction: UpdateGroupMaxSize");
process_update_group_max_size(program_id, accounts, data)
}
TokenGroupInstruction::UpdateGroupAuthority(data) => {
msg!("Instruction: UpdateCollectionAuthority");
process_update_collection_authority(program_id, accounts, data)
msg!("Instruction: UpdateGroupAuthority");
process_update_group_authority(program_id, accounts, data)
}
TokenGroupInstruction::InitializeMember(_) => {
msg!("Instruction: InitializeCollectionMember");
process_initialize_collection_member(program_id, accounts)
msg!("Instruction: InitializeMember");
process_initialize_member(program_id, accounts)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ use {
};

#[tokio::test]
async fn test_initialize_collection() {
async fn test_initialize_group() {
let program_id = Pubkey::new_unique();
let collection = Keypair::new();
let collection_mint = Keypair::new();
let collection_mint_authority = Keypair::new();
let group = Keypair::new();
let group_mint = Keypair::new();
let group_mint_authority = Keypair::new();

let collection_group_state = TokenGroup {
let group_state = TokenGroup {
update_authority: None.try_into().unwrap(),
size: 0.into(),
max_size: 50.into(),
Expand All @@ -37,11 +37,11 @@ async fn test_initialize_collection() {
let token_client = Token::new(
client,
&spl_token_2022::id(),
&collection_mint.pubkey(),
&group_mint.pubkey(),
Some(0),
payer.clone(),
);
setup_mint(&token_client, &collection_mint, &collection_mint_authority).await;
setup_mint(&token_client, &group_mint, &group_mint_authority).await;

let mut context = context.lock().await;

Expand All @@ -52,26 +52,26 @@ async fn test_initialize_collection() {
// Fail: mint authority not signer
let mut init_group_ix = initialize_group(
&program_id,
&collection.pubkey(),
&collection_mint.pubkey(),
&collection_mint_authority.pubkey(),
collection_group_state.update_authority.try_into().unwrap(),
collection_group_state.max_size.into(),
&group.pubkey(),
&group_mint.pubkey(),
&group_mint_authority.pubkey(),
group_state.update_authority.try_into().unwrap(),
group_state.max_size.into(),
);
init_group_ix.accounts[2].is_signer = false;
let transaction = Transaction::new_signed_with_payer(
&[
system_instruction::create_account(
&context.payer.pubkey(),
&collection.pubkey(),
&group.pubkey(),
rent_lamports,
space.try_into().unwrap(),
&program_id,
),
init_group_ix,
],
Some(&context.payer.pubkey()),
&[&context.payer, &collection],
&[&context.payer, &group],
context.last_blockhash,
);
assert_eq!(
Expand All @@ -84,27 +84,27 @@ async fn test_initialize_collection() {
TransactionError::InstructionError(1, InstructionError::MissingRequiredSignature)
);

// Success: create the collection
// Success: create the group
let transaction = Transaction::new_signed_with_payer(
&[
system_instruction::create_account(
&context.payer.pubkey(),
&collection.pubkey(),
&group.pubkey(),
rent_lamports,
space.try_into().unwrap(),
&program_id,
),
initialize_group(
&program_id,
&collection.pubkey(),
&collection_mint.pubkey(),
&collection_mint_authority.pubkey(),
collection_group_state.update_authority.try_into().unwrap(),
collection_group_state.max_size.into(),
&group.pubkey(),
&group_mint.pubkey(),
&group_mint_authority.pubkey(),
group_state.update_authority.try_into().unwrap(),
group_state.max_size.into(),
),
],
Some(&context.payer.pubkey()),
&[&context.payer, &collection_mint_authority, &collection],
&[&context.payer, &group_mint_authority, &group],
context.last_blockhash,
);
context
Expand All @@ -113,29 +113,29 @@ async fn test_initialize_collection() {
.await
.unwrap();

// Fetch the collection account and ensure it matches our state
let fetched_collection_account = context
// Fetch the group account and ensure it matches our state
let fetched_group_account = context
.banks_client
.get_account(collection.pubkey())
.get_account(group.pubkey())
.await
.unwrap()
.unwrap();
let fetched_meta = TlvStateBorrowed::unpack(&fetched_collection_account.data).unwrap();
let fetched_collection_group_state = fetched_meta.get_first_value::<TokenGroup>().unwrap();
assert_eq!(fetched_collection_group_state, &collection_group_state);
let fetched_meta = TlvStateBorrowed::unpack(&fetched_group_account.data).unwrap();
let fetched_group_state = fetched_meta.get_first_value::<TokenGroup>().unwrap();
assert_eq!(fetched_group_state, &group_state);

// Fail: can't initialize twice
let transaction = Transaction::new_signed_with_payer(
&[initialize_group(
&program_id,
&collection.pubkey(),
&collection_mint.pubkey(),
&collection_mint_authority.pubkey(),
&group.pubkey(),
&group_mint.pubkey(),
&group_mint_authority.pubkey(),
Pubkey::new_unique().into(), // Intentionally changed
collection_group_state.max_size.into(),
group_state.max_size.into(),
)],
Some(&context.payer.pubkey()),
&[&context.payer, &collection_mint_authority],
&[&context.payer, &group_mint_authority],
context.last_blockhash,
);
assert_eq!(
Expand Down
Loading

0 comments on commit c46f300

Please sign in to comment.