Skip to content

Commit

Permalink
token 2022: add GroupMemberPointer extension
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Nov 20, 2023
1 parent a62d81f commit 9c4d472
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 226 deletions.
10 changes: 0 additions & 10 deletions token/client/src/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,6 @@ pub enum ExtensionInitializationParams {
},
GroupMemberPointer {
authority: Option<Pubkey>,
group_update_authority: Pubkey,
group_address: Pubkey,
member_address: Option<Pubkey>,
},
}
Expand Down Expand Up @@ -303,15 +301,11 @@ impl ExtensionInitializationParams {
),
Self::GroupMemberPointer {
authority,
group_update_authority,
group_address,
member_address,
} => group_member_pointer::instruction::initialize(
token_program_id,
mint,
authority,
&group_update_authority,
&group_address,
member_address,
),
}
Expand Down Expand Up @@ -1724,8 +1718,6 @@ where
pub async fn update_group_member_address<S: Signers>(
&self,
authority: &Pubkey,
group_update_authority: &Pubkey,
group_address: &Pubkey,
new_member_address: Option<Pubkey>,
signing_keypairs: &S,
) -> TokenResult<T::Output> {
Expand All @@ -1737,9 +1729,7 @@ where
&self.program_id,
self.get_address(),
authority,
group_update_authority,
&multisig_signers,
group_address,
new_member_address,
)?],
signing_keypairs,
Expand Down
153 changes: 12 additions & 141 deletions token/program-2022-test/tests/group_member_pointer.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
#![cfg(feature = "test-sbf")]

use {
solana_program::system_instruction, solana_program_test::tokio::sync::Mutex,
spl_token_2022::extension::ExtensionType,
};

mod program_test;
use {
program_test::{TestContext, TokenContext},
solana_program_test::{processor, tokio, ProgramTest, ProgramTestContext},
solana_program_test::{
processor,
tokio::{self, sync::Mutex},
ProgramTest, ProgramTestContext,
},
solana_sdk::{
account::Account as SolanaAccount,
instruction::InstructionError,
Expand All @@ -21,14 +20,10 @@ use {
spl_token_2022::{
error::TokenError,
extension::{
group_member_pointer::{
instruction::{initialize, update},
GroupMemberPointer,
},
group_member_pointer::{instruction::update, GroupMemberPointer},
BaseStateWithExtensions,
},
processor::Processor,
state::Mint,
},
spl_token_client::token::{ExtensionInitializationParams, TokenError as TokenClientError},
std::{convert::TryInto, sync::Arc},
Expand Down Expand Up @@ -91,26 +86,21 @@ async fn setup_token_group(
async fn setup_member_mint(
context: Arc<Mutex<ProgramTestContext>>,
mint: Keypair,
group_address: &Pubkey,
authority: &Pubkey,
group_update_authority: &Keypair,
) -> TestContext {
let mut context = TestContext {
context,
token_context: None,
};
let member_address = Some(mint.pubkey());
context
.init_token_with_mint_keypair_and_freeze_authority_and_additional_signers(
.init_token_with_mint_keypair_and_freeze_authority(
mint,
vec![ExtensionInitializationParams::GroupMemberPointer {
authority: Some(*authority),
group_address: *group_address,
group_update_authority: group_update_authority.pubkey(),
member_address,
}],
None,
&[&group_update_authority],
)
.await
.unwrap();
Expand Down Expand Up @@ -158,9 +148,7 @@ async fn success_init() {
let member_token = setup_member_mint(
context,
member_mint.insecure_clone(),
&group_mint.pubkey(),
&member_authority.pubkey(),
&group_update_authority,
)
.await
.token_context
Expand All @@ -175,7 +163,6 @@ async fn success_init() {
extension.authority,
Some(member_authority.pubkey()).try_into().unwrap()
);
assert_eq!(extension.group_address, group_mint.pubkey());
assert_eq!(
extension.member_address,
Some(member_mint.pubkey()).try_into().unwrap()
Expand All @@ -187,8 +174,6 @@ async fn fail_init() {
let payer = Keypair::new();
let group_mint = Keypair::new();
let group_update_authority = Keypair::new();
let member_mint = Keypair::new();
let member_authority = Keypair::new();

let program_test = setup_program_test();
let mut context = program_test.start_with_context().await;
Expand Down Expand Up @@ -226,16 +211,13 @@ async fn fail_init() {
token_context: None,
};
let err = context
.init_token_with_mint_keypair_and_freeze_authority_and_additional_signers(
.init_token_with_mint_keypair_and_freeze_authority(
Keypair::new(),
vec![ExtensionInitializationParams::GroupMemberPointer {
authority: None,
group_address: group_mint.pubkey(),
group_update_authority: group_update_authority.pubkey(),
member_address: None,
}],
None,
&[&group_update_authority],
)
.await
.unwrap_err();
Expand All @@ -248,53 +230,6 @@ async fn fail_init() {
)
)))
);

// fail missing group update authority signature
let mut context = context.context.lock().await;
let space =
ExtensionType::try_calculate_account_len::<Mint>(&[ExtensionType::GroupMemberPointer])
.unwrap();
let lamports = context
.banks_client
.get_rent()
.await
.unwrap()
.minimum_balance(space);
let mut instruction = initialize(
&spl_token_2022::id(),
&member_mint.pubkey(),
Some(member_authority.pubkey()),
&group_update_authority.pubkey(),
&group_mint.pubkey(),
Some(member_mint.pubkey()),
)
.unwrap();
instruction.accounts[2].is_signer = false;
let transaction = Transaction::new_signed_with_payer(
&[
system_instruction::create_account(
&payer.pubkey(),
&member_mint.pubkey(),
lamports,
space as u64,
&spl_token_2022::id(),
),
instruction,
],
Some(&payer.pubkey()),
&[&payer, &member_mint],
context.last_blockhash,
);
let error = context
.banks_client
.process_transaction(transaction)
.await
.unwrap_err()
.unwrap();
assert_eq!(
error,
TransactionError::InstructionError(1, InstructionError::MissingRequiredSignature,)
);
}

#[tokio::test]
Expand Down Expand Up @@ -338,9 +273,7 @@ async fn success_update() {
let member_token = setup_member_mint(
context.clone(),
member_mint.insecure_clone(),
&group_mint.pubkey(),
&member_authority.pubkey(),
&group_update_authority,
)
.await
.token_context
Expand All @@ -354,8 +287,6 @@ async fn success_update() {
member_token
.update_group_member_address(
&member_authority.pubkey(),
&group_update_authority.pubkey(),
&group_mint.pubkey(),
Some(new_member_address),
&[&group_update_authority, &member_authority],
)
Expand All @@ -368,7 +299,6 @@ async fn success_update() {
extension.authority,
Some(member_authority.pubkey()).try_into().unwrap()
);
assert_eq!(extension.group_address, group_mint.pubkey());
assert_eq!(
extension.member_address,
Some(new_member_address).try_into().unwrap()
Expand All @@ -378,8 +308,6 @@ async fn success_update() {
member_token
.update_group_member_address(
&member_authority.pubkey(),
&group_update_authority.pubkey(),
&group_mint.pubkey(),
None,
&[&group_update_authority, &member_authority],
)
Expand All @@ -392,7 +320,6 @@ async fn success_update() {
extension.authority,
Some(member_authority.pubkey()).try_into().unwrap()
);
assert_eq!(extension.group_address, group_mint.pubkey());
assert_eq!(extension.member_address, None.try_into().unwrap());
}

Expand Down Expand Up @@ -437,9 +364,7 @@ async fn fail_update() {
let member_token = setup_member_mint(
context.clone(),
member_mint.insecure_clone(),
&group_mint.pubkey(),
&member_authority.pubkey(),
&group_update_authority,
)
.await
.token_context
Expand All @@ -450,33 +375,10 @@ async fn fail_update() {
let wrong = Keypair::new();
let new_member_address = Pubkey::new_unique();

// fail, wrong signature for group update authority
let err = member_token
.update_group_member_address(
&member_authority.pubkey(),
&wrong.pubkey(),
&group_mint.pubkey(),
Some(new_member_address),
&[&wrong, &member_authority],
)
.await
.unwrap_err();
assert_eq!(
err,
TokenClientError::Client(Box::new(TransportError::TransactionError(
TransactionError::InstructionError(
0,
InstructionError::Custom(TokenError::OwnerMismatch as u32)
)
)))
);

// fail, wrong signature for member pointer authority
// fail, wrong signature for authority
let err = member_token
.update_group_member_address(
&wrong.pubkey(),
&group_update_authority.pubkey(),
&group_mint.pubkey(),
Some(new_member_address),
&[&group_update_authority, &wrong],
)
Expand All @@ -494,51 +396,20 @@ async fn fail_update() {

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

// fail, missing group update authority signature
// fail, missing authority signature
let mut instruction = update(
&spl_token_2022::id(),
&member_mint.pubkey(),
&member_authority.pubkey(),
&group_update_authority.pubkey(),
&[],
&group_mint.pubkey(),
Some(member_mint.pubkey()),
)
.unwrap();
instruction.accounts[3].is_signer = false;
let transaction = Transaction::new_signed_with_payer(
&[instruction],
Some(&payer.pubkey()),
&[&payer, &member_authority],
context.last_blockhash,
);
let error = context
.banks_client
.process_transaction(transaction)
.await
.unwrap_err()
.unwrap();
assert_eq!(
error,
TransactionError::InstructionError(0, InstructionError::MissingRequiredSignature,)
);

// fail, missing member pointer authority signature
let mut instruction = update(
&spl_token_2022::id(),
&member_mint.pubkey(),
&member_authority.pubkey(),
&group_update_authority.pubkey(),
&[],
&group_mint.pubkey(),
Some(member_mint.pubkey()),
)
.unwrap();
instruction.accounts[2].is_signer = false;
instruction.accounts[1].is_signer = false;
let transaction = Transaction::new_signed_with_payer(
&[instruction],
Some(&payer.pubkey()),
&[&payer, &group_update_authority],
&[&payer],
context.last_blockhash,
);
let error = context
Expand Down
Loading

0 comments on commit 9c4d472

Please sign in to comment.