Skip to content

Commit ca7caed

Browse files
committed
DRY for failure builders
1 parent a5ba078 commit ca7caed

2 files changed

Lines changed: 78 additions & 110 deletions

File tree

p-ata/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ Expanded Functionality:
1616

1717
- `RecoverNested` works with multisig accounts (satisfying [#24](https://github.com/solana-program/associated-token-account/issues/24))
1818
- `CreateAccountPrefunded` is supported for cheaper calls of p-ata's `Create` when the account rent has been topped up in advance. Conditional on [SIMD-312](https://github.com/solana-foundation/solana-improvement-documents/pull/312), but alternative code is provided if `not(feature = "create-account-prefunded")`. Enabling this feature saves this flow ~2500 CUs (Compute Units). Currently, branches of `agave`, `system`, `pinocchio`, and `mollusk` with `CreateAccountPrefunded` support are patched in.
19-
- In descending order of significance,`bump`, `rent`, and (TokenAccount) `len` can be passed in by client to save compute.
19+
- In descending order of significance,`bump`, `rent`, and (TokenAccount) `token_account_len` can be passed in by client to save compute.
2020

2121
## Testing and Benchmarking
2222

@@ -28,7 +28,7 @@ Mollusk's extensive debug logs are filtered out unless a test has an unexpected
2828

2929
"optimum args" are:
3030
- `bump`
31-
- for Token-2022, `len` passed in the data
31+
- for Token-2022, `token_account_len` passed in the data
3232
- for some items, `rent` passed in as an optional additional account
3333

3434
| Test | SPL ATA | p-ata, no new args | p-ata w/ bump | p-ata w/ optimum args | Notes |

p-ata/benches/failure_scenarios.rs

Lines changed: 76 additions & 108 deletions
Original file line numberDiff line numberDiff line change
@@ -606,21 +606,31 @@ impl FailureTestBuilder {
606606
(ix, accounts)
607607
}
608608

609-
/// Custom builder for wrong token account size test
610-
fn build_fail_wrong_token_account_size(
609+
/// Generic helper for CreateIdempotent failure tests that have an existing ATA
610+
fn build_create_idempotent_failure_test<F>(
611611
ata_impl: &AtaImplementation,
612612
token_program_id: &Pubkey,
613-
) -> (Instruction, Vec<(Pubkey, Account)>) {
613+
test_name: &'static str,
614+
failure_applicator: F,
615+
) -> (Instruction, Vec<(Pubkey, Account)>)
616+
where
617+
F: FnOnce(
618+
&mut Vec<(Pubkey, Account)>,
619+
&Pubkey, // ata
620+
&Pubkey, // mint
621+
&Pubkey, // wallet
622+
&AtaImplementation,
623+
),
624+
{
614625
let (payer, mint, wallet) = build_base_failure_accounts(
615626
BaseTestType::CreateIdempotent,
616627
TestVariant::BASE,
617628
ata_impl,
618629
token_program_id,
619630
);
620631

621-
// Log test name for identification
622632
log_test_info(
623-
"fail_wrong_token_account_size",
633+
test_name,
624634
ata_impl,
625635
&[("payer", &payer), ("mint", &mint), ("wallet", &wallet)],
626636
);
@@ -634,8 +644,8 @@ impl FailureTestBuilder {
634644
.with_existing_ata(&mint, &wallet, token_program_id)
635645
.to_vec();
636646

637-
// Apply failure: set ATA to wrong size
638-
FailureAccountBuilder::set_wrong_data_size(&mut accounts, ata, 100);
647+
// Apply the specific failure condition to the accounts
648+
failure_applicator(&mut accounts, &ata, &mint, &wallet, ata_impl);
639649

640650
let ix = Instruction {
641651
program_id: ata_impl.program_id,
@@ -653,128 +663,86 @@ impl FailureTestBuilder {
653663
(ix, accounts)
654664
}
655665

666+
/// Custom builder for wrong token account size test
667+
fn build_fail_wrong_token_account_size(
668+
ata_impl: &AtaImplementation,
669+
token_program_id: &Pubkey,
670+
) -> (Instruction, Vec<(Pubkey, Account)>) {
671+
Self::build_create_idempotent_failure_test(
672+
ata_impl,
673+
token_program_id,
674+
"fail_wrong_token_account_size",
675+
|accounts, ata, _mint, _wallet, _ata_impl| {
676+
// Apply failure: set ATA to wrong size
677+
FailureAccountBuilder::set_wrong_data_size(accounts, *ata, 100);
678+
},
679+
)
680+
}
681+
656682
/// Custom builder for token account wrong mint test
657683
fn build_fail_token_account_wrong_mint(
658684
ata_impl: &AtaImplementation,
659685
token_program_id: &Pubkey,
660686
) -> (Instruction, Vec<(Pubkey, Account)>) {
661-
let (payer, mint, wallet) = build_base_failure_accounts(
662-
BaseTestType::CreateIdempotent,
663-
TestVariant::BASE,
687+
Self::build_create_idempotent_failure_test(
664688
ata_impl,
665689
token_program_id,
666-
);
667-
668-
// Log test name for identification
669-
log_test_info(
670690
"fail_token_account_wrong_mint",
671-
ata_impl,
672-
&[("payer", &payer), ("mint", &mint), ("wallet", &wallet)],
673-
);
674-
675-
let test_number = common_builders::calculate_failure_test_number(
676-
BaseTestType::CreateIdempotent,
677-
TestVariant::BASE,
678-
);
679-
let wrong_mint = crate::common::structured_pk(
680-
&ata_impl.variant,
681-
crate::common::TestBankId::Failures,
682-
test_number + 1,
683-
crate::common::AccountTypeId::Mint,
684-
);
685-
let (ata, _bump) = Pubkey::find_program_address(
686-
&[wallet.as_ref(), token_program_id.as_ref(), mint.as_ref()],
687-
&ata_impl.program_id,
688-
);
689-
690-
let mut accounts =
691-
StandardAccountSet::new(payer, ata, wallet, mint, token_program_id).to_vec();
692-
693-
// Replace ATA with one pointing to wrong mint
694-
if let Some(pos) = accounts.iter().position(|(addr, _)| *addr == ata) {
695-
accounts[pos].1 =
696-
AccountBuilder::token_account(&wrong_mint, &wallet, 0, token_program_id);
697-
}
698-
699-
// Add the wrong mint account
700-
accounts.push((
701-
wrong_mint,
702-
AccountBuilder::mint_account(0, token_program_id, false),
703-
));
691+
|accounts, ata, _mint, wallet, ata_impl| {
692+
let test_number = common_builders::calculate_failure_test_number(
693+
BaseTestType::CreateIdempotent,
694+
TestVariant::BASE,
695+
);
696+
let wrong_mint = crate::common::structured_pk(
697+
&ata_impl.variant,
698+
crate::common::TestBankId::Failures,
699+
test_number + 1,
700+
crate::common::AccountTypeId::Mint,
701+
);
704702

705-
let ix = Instruction {
706-
program_id: ata_impl.program_id,
707-
accounts: vec![
708-
AccountMeta::new(payer, true),
709-
AccountMeta::new(ata, false),
710-
AccountMeta::new_readonly(wallet, false),
711-
AccountMeta::new_readonly(mint, false),
712-
AccountMeta::new_readonly(SYSTEM_PROGRAM_ID, false),
713-
AccountMeta::new_readonly(*token_program_id, false),
714-
],
715-
data: vec![1u8], // CreateIdempotent instruction
716-
};
703+
// Replace ATA with one pointing to wrong mint
704+
if let Some(pos) = accounts.iter().position(|(addr, _)| *addr == *ata) {
705+
accounts[pos].1 =
706+
AccountBuilder::token_account(&wrong_mint, wallet, 0, token_program_id);
707+
}
717708

718-
(ix, accounts)
709+
// Add the wrong mint account
710+
accounts.push((
711+
wrong_mint,
712+
AccountBuilder::mint_account(0, token_program_id, false),
713+
));
714+
},
715+
)
719716
}
720717

721718
/// Custom builder for token account wrong owner test
722719
fn build_fail_token_account_wrong_owner(
723720
ata_impl: &AtaImplementation,
724721
token_program_id: &Pubkey,
725722
) -> (Instruction, Vec<(Pubkey, Account)>) {
726-
let (payer, mint, wallet) = build_base_failure_accounts(
727-
BaseTestType::CreateIdempotent,
728-
TestVariant::BASE,
723+
Self::build_create_idempotent_failure_test(
729724
ata_impl,
730725
token_program_id,
731-
);
732-
733-
// Log test name for identification
734-
log_test_info(
735726
"fail_token_account_wrong_owner",
736-
ata_impl,
737-
&[("payer", &payer), ("mint", &mint), ("wallet", &wallet)],
738-
);
739-
740-
let test_number = common_builders::calculate_failure_test_number(
741-
BaseTestType::CreateIdempotent,
742-
TestVariant::BASE,
743-
);
744-
let wrong_owner = crate::common::structured_pk(
745-
&ata_impl.variant,
746-
crate::common::TestBankId::Failures,
747-
test_number + 1,
748-
crate::common::AccountTypeId::Wallet,
749-
);
750-
let (ata, _bump) = Pubkey::find_program_address(
751-
&[wallet.as_ref(), token_program_id.as_ref(), mint.as_ref()],
752-
&ata_impl.program_id,
753-
);
754-
755-
let mut accounts =
756-
StandardAccountSet::new(payer, ata, wallet, mint, token_program_id).to_vec();
757-
758-
// Replace ATA with one having wrong owner
759-
if let Some(pos) = accounts.iter().position(|(addr, _)| *addr == ata) {
760-
accounts[pos].1 =
761-
AccountBuilder::token_account(&mint, &wrong_owner, 0, token_program_id);
762-
}
763-
764-
let ix = Instruction {
765-
program_id: ata_impl.program_id,
766-
accounts: vec![
767-
AccountMeta::new(payer, true),
768-
AccountMeta::new(ata, false),
769-
AccountMeta::new_readonly(wallet, false),
770-
AccountMeta::new_readonly(mint, false),
771-
AccountMeta::new_readonly(SYSTEM_PROGRAM_ID, false),
772-
AccountMeta::new_readonly(*token_program_id, false),
773-
],
774-
data: vec![1u8], // CreateIdempotent instruction
775-
};
727+
|accounts, ata, mint, _wallet, ata_impl| {
728+
let test_number = common_builders::calculate_failure_test_number(
729+
BaseTestType::CreateIdempotent,
730+
TestVariant::BASE,
731+
);
732+
let wrong_owner = crate::common::structured_pk(
733+
&ata_impl.variant,
734+
crate::common::TestBankId::Failures,
735+
test_number + 1,
736+
crate::common::AccountTypeId::Wallet,
737+
);
776738

777-
(ix, accounts)
739+
// Replace ATA with one having wrong owner
740+
if let Some(pos) = accounts.iter().position(|(addr, _)| *addr == *ata) {
741+
accounts[pos].1 =
742+
AccountBuilder::token_account(mint, &wrong_owner, 0, token_program_id);
743+
}
744+
},
745+
)
778746
}
779747

780748
/// Custom builder: use original Token program but provide an extended (Token-2022 style) mint

0 commit comments

Comments
 (0)